Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
recaptcha — Documentation et rétro-ingénierie de reCAPTCHA | Kitploit
Outils/GitHubGitHub/elyelysiox/recaptcha
Analyse StatiqueAnalyse Dynamique de Code (DAST)Rétro-ingénierieSécurité WebAnti-BotContournement de CAPTCHA
GitHubelyelysiox/recaptcha

recaptcha

Documentation et rétro-ingénierie de reCAPTCHA

Voir le dépôt
2273858il y a 3 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Description

Ce dépôt contient une analyse technique de l'antibot de Google (reCAPTCHA), en se concentrant sur :

  • Structure et valeurs des charges utiles
  • Techniques d'empreinte numérique
  • Techniques d'obscurcissement
  • Techniques anti-débogage/anti-modification
  • Machines virtuelles

Contact

  • Discord : @g_recaptcha
  • Telegram : @lyxlobyx

Techniques d'obscurcissement

reCAPTCHA est l'un des systèmes anti-bot dotés des techniques d'obscurcissement les plus sophistiquées, employant une série de transformations qui rendent le code moins lisible et plus difficile à rétro-ingénier. La plupart des obscurcissements peuvent être facilement manipulés à l'aide de l'arbre syntaxique abstrait (AST), mais certains sont traités au moment de l'exécution, rendant l'AST inutile dans ce cas. Le polymorphisme est également appliqué au code pour modifier sa structure dans chaque version du script. Par exemple, le code n'effectue pas l'action directement. Au lieu de cela, il utilise des objets ou des fonctions qui changent de forme

  • Expressions de séquence Le code est aplati en convertissant chaque bloc d'instructions en une expression continue séparée par des virgules. Cela peut apparaître dans les instructions if, les arguments de fonction, et même à l'intérieur d'objets seq

  • Arithmétique booléenne mixte Entremêle des opérations arithmétiques (addition, soustraction, multiplication) avec des opérations bit à bit (ET, OU, XOR, NON) pour masquer la logique originale, par exemple -2 * ~(h & H) + -2 + (h ^ H)

  • Table de fonctions indirecte Chaque fonction est construite dans une table et est appelée en utilisant son index, comme functions[index](https://github.com/elyelysiox/recaptcha/blob/main/args)

  • Tableau de constantes en ligne Un littéral de tableau local est affecté en ligne, au milieu d'une expression. Le tableau regroupe des constantes (nombres, chaînes) qui sont réutilisées dans tout le corps de la fonction via un accès par index

    // b = [14, 1, "call"] assigné en ligne dans une expression de séquence
    function(Y, Q, c, l, G, X, W, J, b, P) {
        (Y & 94) == Y && (b = [14, 1, "call"], ...)
        W[b[2]](J, G)   // W.call(J, G)
        Y >> b[1] & b[0]  // Y >> 1 & 14
    }
    
  • Multiplexage de fonctions Plusieurs fonctions logiquement distinctes sont fusionnées en une seule, en utilisant un paramètre numérique comme sélecteur de bloc. Le bloc actif est déterminé en évaluant le paramètre par rapport à des conditions bit à bit. Les appelants passent un littéral numérique comme sélecteur.

    function(N, y, U, Y, h, H, m, C, u) {
        C = [26, 47, 6];
    
        // bloc 1
        if ((N - 2 ^ 14) < N && (N - C[2] | 28) >= N) {
            // logique de conversion de valeur en chaîne
        }
    
        // bloc 2
        if ((N + 4 & 40) >= N && (N + 5 & C[0]) < N) {
            Y = bB();
            throw Error(Y === void 0 ? "valeur inattendue " + U + y : Y);
        }
    
        return u;
    }
    
  • Branchement par opérateurs logiques Remplace les blocs if et if/else par l'évaluation en court-circuit des opérateurs logiques, convertissant le flux de contrôle en expressions. Combiné avec des expressions de séquence, plusieurs branches apparaissent comme une seule expression continue séparée par des virgules

    // if (a) { bloc }
    a && (bloc)
    
    // if (!a) { bloc }
    a || (bloc)
    
    // if (a) { x } else { y }
    a ? x : y
    
    // combiné avec CFF et expressions de séquence :
    (Y | 1) & 14 || (c = Q.O, J = c.O.length + c.g.length),
    (Y ^ 59) >> 3 == 3 && (Q.classList
        ? Q.classList.add(c)
        : Z[31](31, Q, c) || (l = f[0](84, "string", "", Q), ...)),
    
  • Liaison de constantes de méthodes natives Lie les méthodes natives du navigateur à leurs récepteurs d'origine, les stockant en tant que constantes pour empêcher toute modification

    LO = (Tw = self) == null ? void 0 :
     (K9 = Tw.Math) == null ? void 0 :
     (v4 = K9.floor) == null ? void 0 :
     (mF = v4.bind) == null ? void 0 :
     mF.call(v4, Math)  // Math.floor.bind(Math)
    
    LO(x)           // Math.floor(x)
    U4()            // Math.random()
    Ge(obj, prop)   // Object.defineProperty(obj, prop)
    
  • Code mort Des blocs de code inaccessibles ou inutilisés sont injectés dans tout le fichier, augmentant sa taille à plus de 60 000 lignes, ce qui rend l'analyse statique et la rétro-ingénierie par LLM difficiles

  • Aplatissement du flux de contrôle Transforme chaque partie du code (déclarations et boucles) en une machine d'état plate. Cela masque la logique d'exécution d'origine en acheminant tous les blocs de code via un bloc « répartiteur » central

    Les répartiteurs peuvent changer de forme ; certains ont 2-3 variables d'état, et le type de boucle/condition change. Ils ressemblent à ceci

    cff1

    Ceci est un CFF avec 2 variables d'état, l'une gère le bloc catch et l'autre le bloc try.

  • Pool de chaînes chiffrées Tous les littéraux de chaîne (API DOM, propriétés du navigateur, valeurs CSS, messages d'erreur, etc.) sont chiffrés en un seul pool de chaînes massif. Une fonction de déchiffrement utilise une graine et un chiffrement XOR basé sur LCG pour extraire chaque chaîne au moment de l'exécution

    Il y a plus de 1990 sites d'appel répartis dans le code. La fonction de déchiffrement utilise une clé courante qui accumule les points de code décodés, rendant chaque caractère dépendant de tous les précédents

    X = function(J, b, P, F, U) {
        U = ["codePointAt", 127, "pool chiffré de chars"];
        for (F = (P = 0, b = "", l); P < Q; P++)
            J = (U[2][U[0]](c + P) ^ F) & U[1],  // XOR avec clé courante
            b += String.fromCodePoint(J),
            F += J; // accumule la clé
        return G = b;
    }
    
    // les sites d'appel passent une graine pour localiser et déchiffrer chaque chaîne
    Z[23](64, 4, 54961, 103)()  // → "lang"
    Z[23](66, 4, 54961, 103)()  // → "addEventListener"
    Z[23](32, 12, 20287, 852)() // → "inline-block"
    

    decstrings

  • Itérateur de valeurs avec état reCAPTCHA utilise une fonction avec état qui renvoie une séquence d'objets et de valeurs d'exécution (comme window, document.body, des constantes numériques) dans un ordre fixe ; chaque appel avance un curseur interne. L'appeler dans le désordre ou trop de fois corrompt toutes les lectures ultérieures. Un mécanisme d'expiration invalide l'état après un intervalle fixe, renvoyant null pour toutes les lectures tardives

    // les appels séquentiels renvoient des valeurs différentes :
    c()  // → window
    c()  // → document.body
    c()  // → 123
    c()  // → null (expiration dépassée)
    
    l(c(), G[2], G[W[1]], G[1]) + l(c(), G[2], G[W[1]], 12)
    // ↑ window                     ↑ window
    
    10 * l(c(), G[2], G[W[1]], G[1]) + l(c(), G[2], G[W[1]], 12))
    
    c().querySelectorAll(a[X[2]](98, X[1], X[1]))
    // ↑ document.body  
    
    
Télécharger l’outil