Spaces:
Paused
Paused
File size: 3,275 Bytes
34367da | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | import 'dotenv/config';
import neo4j from 'neo4j-driver';
import * as path from 'path';
import { fileURLToPath } from 'url';
// SHIM: Define __dirname for ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const RANSOMWATCH_FEED = 'https://raw.githubusercontent.com/joshhighet/ransomwatch/main/posts.json';
async function harvestDarkWeb() {
console.log('🌑 Operation Dark Sentry: Initializing...');
const uri = process.env.NEO4J_URI;
const user = process.env.NEO4J_USER;
const password = process.env.NEO4J_PASSWORD;
if (!uri || !user || !password) {
console.error('❌ ERROR: Missing Neo4j credentials');
process.exit(1);
}
const driver = neo4j.driver(uri, neo4j.auth.basic(user, password));
const session = driver.session();
try {
console.log('📡 Intercepting Ransomwatch feed...');
const response = await fetch(RANSOMWATCH_FEED);
if (!response.ok) throw new Error(`Failed to fetch feed: ${response.statusText}`);
const allPosts = await response.json() as any[];
console.log(`📦 Intercepted ${allPosts.length} leak posts.`);
// Sort by date descending and take top 50
const recentPosts = allPosts
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
.slice(0, 50);
console.log(`⚡ Processing ${recentPosts.length} most recent threats...`);
let nodesCreated = 0;
const groupCounts: Record<string, number> = {};
for (const post of recentPosts) {
// Data normalization
const actorName = post.group_name || 'Unknown Actor';
const victimTitle = post.post_title || 'Unknown Victim';
const date = post.discovered || new Date().toISOString();
groupCounts[actorName] = (groupCounts[actorName] || 0) + 1;
await session.run(`
MERGE (actor:ThreatActor {name: $actorName})
ON CREATE SET actor.firstSeen = $date
ON MATCH SET actor.lastSeen = $date
MERGE (victim:Victim {name: $victimTitle})
ON CREATE SET victim.discovered = $date
MERGE (actor)-[r:TARGETED]->(victim)
SET r.date = $date, r.source = 'ransomwatch'
`, { actorName, victimTitle, date });
nodesCreated++;
if (nodesCreated % 10 === 0) process.stdout.write('.');
}
console.log(`\n✅ Intelligence Injection Complete. Processed ${nodesCreated} attacks.`);
// Sort groups by activity
const topGroups = Object.entries(groupCounts)
.sort(([,a], [,b]) => b - a)
.slice(0, 3);
console.log('\n📊 Top Active Threat Actors (Recent Sample):');
topGroups.forEach(([group, count]) => console.log(`- ${group}: ${count} victims`));
} catch (error) {
console.error('💥 Sentry Failure:', error);
} finally {
await session.close();
await driver.close();
}
}
harvestDarkWeb();
|