Explorer
KNOW-PAT-075

Honeypot anti-extension - Detection de bypass via modal.min.js et ban définitif

Domaine
cybersecu
Type
pattern
Priorité
P2

Parent : [[INDEX-CYBERSECU]]

Honeypot anti-extension - Detection de bypass via modal.min.js et ban définitif

Problème

Un script chargé sur toutes les pages, renommé de security.min.js à modal.min.js pour passer inaperçu. Le contenu est obfusqué en base64. Le script attend 2,5 secondes, puis cherche un élément .yggsearch-api-btn dans la page (une classe injectée par l'extension navigateur YGGMollo). Si l'élément est détecté, un formulaire caché soumet un POST silencieux vers /engine/gm. Le serveur log le user ID, le pseudo et l'IP dans extension_users.txt, puis ban définitivement le compte sans avertissement (sanction_5: "oo" = ban permanent).

Contexte archive Ygg

  • Source : https://yggleak.top/fr/home/ygg-dossier
  • Fichier : modal.min.js (anciennement security.min.js)
  • Extension ciblée : YGGMollo (extension Chrome pour contourner la limite de 5 téléchargements/jour)
  • Endpoint : /engine/gm (gm = get modal, nom anodin)
  • Log : extension_users.txt
  • Sanction : sanction_5: "oo" (ban permanent)
  • Victimes : 13+ utilisateurs identifiés dans extension_users.txt

Technique de l'attaquant (site YGG)

1. Renommage pour passer inaperçu

Rename-Item -Path "assets\js\security.min.js" -NewName "modal.min.js"

2. Obfuscation en base64

var _c=[atob('LnlnZ3NlYXJjaC1hcGktYnRu'),atob('L2VuZ2luZS9nbQ==')];
// decode : selecteur = '.yggsearch-api-btn', endpoint = '/engine/gm'

3. Détection et ban

// Le script attend 2.5 secondes
setTimeout(() => {
  const target = document.querySelector('.yggsearch-api-btn');
  if (target) {
    // Formulaire caché POST silencieux vers /engine/gm
    const form = document.createElement('form');
    form.action = '/engine/gm';
    form.method = 'POST';
    form.style.display = 'none';
    document.body.appendChild(form);
    form.submit();
    
    // Ban définitif du compte (sans avertissement)
    // sanction_5: "oo" = ban permanent
  }
}, 2500);

4. Log des utilisateurs piégés

// extension_users.txt
user_id, pseudo, ip, timestamp
13225478, Tyuito, [REDACTED], 2025-12-25 04:06:07
4561732, Kono_yaro, X.X.X.X, 2025-12-25 04:06:17

Solution protectif — Détection de honeypot et protection

1. Détecter les honeypots de détection d'extension

// detect-honeypot.js — Détecter les scripts qui surveillent les extensions
(function() {
  'use strict';
  
  // Surveiller la création de formulaires cachés
  const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      mutation.addedNodes.forEach(node => {
        if (node.tagName === 'FORM') {
          const style = window.getComputedStyle(node);
          const isHidden = style.display === 'none' || style.visibility === 'hidden';
          
          if (isHidden && node.action && node.action.includes('/engine/')) {
            console.warn('[HONEYPOT-DETECT] Formulaire caché suspect détecté!');
            console.warn('  Action:', node.action);
            console.warn('  Method:', node.method);
            
            // Bloquer la soumission
            node.addEventListener('submit', e => {
              e.preventDefault();
              console.warn('[HONEYPOT-BLOCK] Soumission bloquée');
            }, true);
          }
        }
      });
    });
  });
  
  observer.observe(document.body, { childList: true, subtree: true });
  
  // Surveiller les requêtes POST silencieuses
  const originalFetch = window.fetch;
  window.fetch = function(url, options = {}) {
    if (options.method === 'POST' && typeof url === 'string' && url.includes('/engine/')) {
      console.warn('[HONEYPOT-DETECT] Requête POST suspecte:', url);
      console.warn('  Body:', options.body);
      
      // Bloquer la requête
      return Promise.reject(new Error('Honeypot request blocked'));
    }
    return originalFetch.apply(this, arguments);
  };
  
  // Surveiller les setTimeout suspects (2-3 secondes = pattern de honeypot)
  const originalSetTimeout = window.setTimeout;
  window.setTimeout = function(callback, delay, ...args) {
    if (delay >= 2000 && delay <= 3000) {
      // Pattern suspect : timeout de 2-3 secondes pour détecter les extensions
      const callbackString = callback.toString();
      if (callbackString.includes('querySelector') || callbackString.includes('yggsearch')) {
        console.warn('[HONEYPOT-DETECT] setTimeout suspect détecté (délai:', delay, 'ms)');
        // Ne pas exécuter le callback
        return -1;
      }
    }
    return originalSetTimeout(callback, delay, ...args);
  };
})();

2. Détecter les scripts obfusqués en base64

// detect-obfuscated-scripts.js
(function() {
  'use strict';
  
  // Surveiller l'exécution de scripts avec atob/base64
  const originalAtob = window.atob;
  window.atob = function(str) {
    const decoded = originalAtob(str);
    
    // Détecter les patterns suspects dans le décodage
    const suspiciousPatterns = [
      'yggsearch', 'api-btn', 'engine', 'gm', 'extension',
      'bypass', 'limit', 'download'
    ];
    
    if (suspiciousPatterns.some(p => decoded.includes(p))) {
      console.warn('[OBFUSCATION-DETECT] Base64 décodant un pattern suspect:');
      console.warn('  Decoded:', decoded);
      console.trace();
    }
    
    return decoded;
  };
  
  // Surveiller les scripts inline avec atob
  const scripts = document.querySelectorAll('script');
  scripts.forEach(script => {
    if (script.textContent.includes('atob(')) {
      console.warn('[OBFUSCATION-DETECT] Script contenant atob() détecté');
      console.warn('  Source:', script.src || 'inline');
    }
  });
})();

3. Protection contre la détection d'extension (côté extension)

// extension-protection.js — Ne pas injecter de classes identifiables
// ❌ MAUVAIS — Classe identifiable
const button = document.createElement('button');
button.className = 'yggsearch-api-btn'; // ❌ Détectable

// ✅ BON — Classe aléatoire, générée dynamiquement
const randomClass = 'btn-' + Math.random().toString(36).substring(2, 10);
const button = document.createElement('button');
button.className = randomClass;

// ✅ BON — Utiliser des attributs data-* générés dynamiquement
const dataAttr = 'data-' + Math.random().toString(36).substring(2, 6);
button.setAttribute(dataAttr, 'true');

// ✅ BON — Injection via Shadow DOM (isolation)
const shadowHost = document.createElement('div');
const shadow = shadowHost.attachShadow({ mode: 'closed' });
shadow.innerHTML = '<button>Download</button>';
document.body.appendChild(shadowHost);

4. Détection côté serveur (pour les développeurs)

// detect-honeypot-server.php — Détecter si le site est un honeypot
function detectHoneypotBehavior($html) {
    $suspiciousPatterns = [
        // Scripts avec setTimeout de 2-3 secondes
        'setTimeout\s*\(\s*function\s*\(\s*\)\s*\{[^}]*querySelector',
        // Scripts avec atob et des patterns suspects
        'atob\s*\(\s*[\'"]',
        // Formulaires cachés avec action /engine/
        '<form[^>]*action=[\'"]/engine/[^>]*display:\s*none',
        // Requêtes POST silencieuses vers /engine/
        'fetch\s*\(\s*[\'"]/engine/',
    ];
    
    $score = 0;
    foreach ($suspiciousPatterns as $pattern) {
        if (preg_match('/' . $pattern . '/i', $html)) {
            $score += 25;
        }
    }
    
    return $score >= 50; // Probable honeypot si score >= 50
}

5. Éthique — Ne PAS créer de honeypots malveillants

## Éthique des honeypots

Un honeypot doit :
- ✅ Être transparent sur sa présence (terms of service)
- ✅ Ne PAS collecter plus de données que nécessaire
- ✅ Ne PAS ban définitif sans avertissement
- ✅ Ne PAS usurper l'identité d'autres extensions
- ✅ Être utilisé pour la sécurité, pas la rétorsion

Un honeypot ne doit PAS :
- ❌ Bannir définitivement sans avertissement
- ❌ Collecter des données personnelles sans consentement
- ❌ Usurper des classes d'extensions légitimes
- ❌ Être dissimulé comme un script inoffensif (modal.min.js)

Checklist de validation

  • Pas de ban définitif sans avertissement (honeypot = détection, pas rétorsion)
  • Pas de collecte de données personnelles via honeypot
  • Pas d'usurpation de classes d'extensions légitimes
  • Scripts de détection transparents (pas renommés pour passer inaperçu)
  • Détection des formulaires cachés POST vers des endpoints suspects
  • Monitoring des setTimeout de 2-3 secondes avec querySelector
  • Détection des scripts obfusqués en base64 avec atob()
  • Utilisation de Shadow DOM pour isoler les extensions
  • Classes générées dynamiquement (pas de patterns fixes)
  • Éthique : honeypot pour la sécurité, pas la rétorsion

Références

  • Archive Ygg : modal.min.js, extension_users.txt (YGGLeak)
  • OWASP : Honeypot Ethics