Analyse de BotGuard BotGuard Analysis

Reverse engineering du système anti-bot de Google Reverse engineering of Google's anti-bot system

Janvier 2026 - Version 41 January 2026 - Version 41

Powered by RESONEO

Qu'est-ce que BotGuard ? What is BotGuard?

BotGuard est le système de protection anti-bot propriétaire de Google, connu en interne sous le nom de "Web Application Attestation" (WAA). Introduit vers 2013, il est aujourd'hui intégré dans la quasi-totalité des services Google : YouTube, Google Search, reCAPTCHA v3, Google Maps, et bien d'autres.

Contrairement aux CAPTCHAs traditionnels qui demandent une interaction explicite, BotGuard opère de manière totalement invisible. Il collecte en permanence des signaux comportementaux (mouvements de souris, frappes clavier, patterns de scroll, timing des interactions) et les analyse via des algorithmes statistiques sophistiqués pour distinguer un humain d'un bot.

Le script génère un token cryptographique envoyé aux serveurs Google pour validation. Ce token est chiffré avec un algorithme ARX dont la constante magique change régulièrement, rendant toute tentative de contournement par reverse engineering rapidement obsolète.

Cette analyse est basée sur la version 41 du script BotGuard, extrait et déobfusqué à partir des données de challenge. Le code s'exécute dans une machine virtuelle bytecode avec 512 registres pour résister au reverse engineering.

Focus juridique

Google vs SerpApi (2025)

Dans sa plainte contre SerpApi, Google a révélé l'existence de ce système sous le nom de "SearchGuard", vraisemblablement le nom interne de BotGuard pour la protection de Google Search.

"SearchGuard is the product of tens of thousands of person hours and millions of dollars of investment."

Cette déclaration illustre l'importance stratégique de ce système de protection pour Google et les ressources considérables investies dans son développement.

BotGuard is Google's proprietary anti-bot protection system, internally known as "Web Application Attestation" (WAA). Introduced around 2013, it is now integrated into virtually all Google services: YouTube, Google Search, reCAPTCHA v3, Google Maps, and many others.

Unlike traditional CAPTCHAs that require explicit interaction, BotGuard operates completely invisibly. It continuously collects behavioral signals (mouse movements, keystrokes, scroll patterns, interaction timing) and analyzes them using sophisticated statistical algorithms to distinguish humans from bots.

The script generates a cryptographic token sent to Google servers for validation. This token is encrypted with an ARX cipher whose magic constant changes regularly, making any bypass attempt through reverse engineering quickly obsolete.

This analysis is based on version 41 of the BotGuard script, extracted and deobfuscated from challenge data. The code runs in a bytecode virtual machine with 512 registers to resist reverse engineering.

Legal Focus

Google vs SerpApi (2025)

In its complaint against SerpApi, Google revealed the existence of this system under the name "SearchGuard", presumably the internal name for BotGuard protecting Google Search.

"SearchGuard is the product of tens of thousands of person hours and millions of dollars of investment."

This statement illustrates the strategic importance of this protection system for Google and the considerable resources invested in its development.

Documentation Technique Technical Documentation

Identification du Script Script Identification

Informations clés extraites du code source, vérifiées par analyse statique.

Key information extracted from source code, verified through static analysis.

Propriété Property Valeur Value Status
Nom Name BotGuard (Google) Vérifié Verified
Version xo.m = 41 Vérifié Verified
Namespace window.botguard / xo Vérifié Verified
Constructeur principal Main Constructor xo.bg (alias LU) Vérifié Verified
Fonction auxiliaire Auxiliary Function xo.a (alias Pn) Vérifié Verified
Factory challenge xo.fcn_ Vérifié Verified
Licence License Apache-2.0 (SPDX) Vérifié Verified

Objectifs du système System Objectives

Les quatre piliers fonctionnels de BotGuard pour détecter les comportements automatisés.

The four functional pillars of BotGuard for detecting automated behavior.

📊

Collecte comportementale Behavioral Collection

Capture les mouvements souris, frappes clavier, scroll, et touch events avec timing précis.

Captures mouse movements, keystrokes, scroll, and touch events with precise timing.

🔎

Fingerprinting

Génère une empreinte unique basée sur le navigateur, l'environnement, et les interactions.

Generates a unique fingerprint based on browser, environment, and interactions.

🔒

Token cryptographique Cryptographic Token

Produit un token chiffré prouvant l'humanité de l'utilisateur aux serveurs Google.

Produces an encrypted token proving user humanity to Google servers.

⚙️

Protection VM VM Protection

S'exécute dans une machine virtuelle bytecode pour résister au reverse engineering.

Runs in a bytecode virtual machine to resist reverse engineering.

Flux de fonctionnement Operation Flow

Séquence d'exécution complète, de l'initialisation à la génération du token final.

Complete execution sequence, from initialization to final token generation.

INITIALISATION
1
xo.fcn_(challenge...)
  • Crée l'instance D
  • Configure les handlers
2
zV() - Setup initial
  • Init bytecode pu
  • Config crypto B, C
  • Setup registres VM
3
DOM Ready Handler
  • DOMContentLoaded
  • Attache les listeners
4
mL() - Boucle VM
  • Exécute le bytecode
  • Collecte les métriques
5
Génération du Token
  • Sérialise (UTF-8)
  • Compresse Ub()
  • Chiffre J$/ARX
  • Encode (Base64url)
Token Final: "!XXXX..."
INITIALIZATION
1
xo.fcn_(challenge...)
  • Creates D instance
  • Configure handlers
2
zV() - Initial Setup
  • Init bytecode pu
  • Config crypto B, C
  • Setup VM registers
3
DOM Ready Handler
  • DOMContentLoaded
  • Attach listeners
4
mL() - VM Main Loop
  • Execute bytecode
  • Collect metrics
5
Token Generation
  • Serialize (UTF-8)
  • Compress Ub()
  • Encrypt J$/ARX
  • Encode (Base64url)
Final Token: "!XXXX..."

Techniques d'Obfuscation Obfuscation Techniques

Méthodes utilisées pour rendre le code difficile à analyser et à reproduire.

Methods used to make the code difficult to analyze and reproduce.

1. Machine à États (State Machine) 1. State Machine

Pratiquement toutes les fonctions utilisent une machine à états rendant le flux de contrôle difficile à suivre :

Virtually all functions use a state machine making the control flow difficult to follow:

// Pattern obfusqué var N = 79; while(N != 42) if(N == 79) N = 87; else if(N == 87) N = condition ? 26 : R; else if(N == 26) { /* code */ N = R; } else if(N == 90) return g; // ...
// Obfuscated pattern var N = 79; while(N != 42) if(N == 79) N = 87; else if(N == 87) N = condition ? 26 : R; else if(N == 26) { /* code */ N = R; } else if(N == 90) return g; // ...

2. Opérations Bitwise Obscures 2. Obscure Bitwise Operations

Le code utilise des expressions bitwise équivalentes à des opérations simples :

The code uses bitwise expressions equivalent to simple operations:

Expression obfusquée Obfuscated Expression Equivalent Equivalent
-~xx + 1
~x + 2-x + 1
(a|b) - (a&b)a ^ b (XOR)
-~(a&b) + 2*(a^b) + (~a^b)a + b
(a|0) - 2*(a&b) - ~a + ~ba - b

3. Noms de Variables Aléatoires 3. Random Variable Names

Toutes les variables significatives sont renommées en identifiants courts et obscurs :

All meaningful variables are renamed to short, obscure identifiers:

Variable Signification Meaning
Mv ID unique pour event listeners Unique ID for event listeners
yw Compteur de listeners Listeners counter
iN Marqueur "listenable" "Listenable" marker
hf Valeurs ARIA par défaut Default ARIA values
nd Options d'événements Event options

4. Strings Construites Dynamiquement 4. Dynamically Built Strings

var Qg = String.fromCharCode(105,110,116,101,103,67,104,101,99,107,66,121,112,97,115,115); // = "integCheckBypass" var Hs = "closure_uid_" + (Math.random() * 1E9 >>> 0);

Architecture du Système System Architecture

Structure interne du code : classes, registres VM et organisation de la mémoire.

Internal code structure: classes, VM registers and memory organization.

Hiérarchie des Classes Class Hierarchy

Arbre d'héritage des classes principales, de la base OT aux composants UI.

Inheritance tree of main classes, from base OT to UI components.

OT
Base - Disposable
Af
Events
Vw
Listener
ev
Component
Ws
Control
jl
Button
Sv
Event

Registres de la Machine Virtuelle Virtual Machine Registers

Les 18 registres indexés utilisés par la VM pour stocker l'état d'exécution.

The 18 indexed registers used by the VM to store execution state.

Index Nom Name Description
510IPInstruction Pointer
152SPStack Pointer
508ERROR Registre d'erreur Error register
498STATUSStatus flags
468BUFFER Buffer de données Data buffer
302OUTPUT Buffer de sortie Output buffer
256INPUT Buffer d'entrée Input buffer
448HISTORY Historique History
130METRICS Métriques Metrics
117KEY Clé de chiffrement Encryption key
51CRYPTO État crypto Crypto state

Structure de l'Objet Principal (D) Main Object Structure (D)

Organisation des propriétés de l'objet contexte créé à l'initialisation.

Organization of the context object properties created at initialization.

🛠 Identifiants Identifiers
  • g: "create"
  • Lu: "toString"
  • h: ErreurError
  • h$: Dernier timestampLast timestamp
📈 Métriques Metrics
  • W: Compteur généralGeneral counter (1)
  • T: Flag touch (false)
  • H: Flag hover (false)
  • A: Accumulateur tempsTime accumulator (0)
⚙️ Machine Virtuelle Virtual Machine
  • S: Stack []
  • O: Registres/mémoireRegisters/memory []
  • K: Bytecode principalMain bytecode
  • v: Taille bytecodeBytecode size (0)
📦 Buffers
  • pu: Bytecode décodéDecoded bytecode []
  • fz: Données initialesInitial data []
  • Nq: Queue callbacksCallbacks queue []
  • Gn: Historique timingsTimings history []

Système de Chiffrement Encryption System

Algorithme cryptographique propriétaire utilisé pour générer et protéger les tokens.

Proprietary cryptographic algorithm used to generate and protect tokens.

Le cipher utilisé est similaire à Speck de la NSA - un cipher ARX (Add-Rotate-XOR) léger et rapide.

The cipher used is similar to the NSA's Speck - a lightweight and fast ARX (Add-Rotate-XOR) cipher.

Caractéristiques du Cipher ARX ARX Cipher Characteristics

Paramètres techniques du cipher : taille de bloc, rotations et nombre de rounds.

Technical cipher parameters: block size, rotations and number of rounds.

Paramètre Parameter Valeur Value
Taille de bloc Block size 64 bits (2 x 32 bits)
Taille de clé Key size 64 bits
Nombre de rounds Number of rounds 15
Rotation droite Right rotation 8 bits
Rotation gauche Left rotation 3 bits
Constante Constant 3328

Fonction J$ - Cipher ARX (déobfusqué) J$ Function - ARX Cipher (deobfuscated)

Implémentation reconstruite du cipher après déobfuscation du code source.

Reconstructed cipher implementation after source code deobfuscation.

function arxCipher(rotateRight, initVector, key1, key2, rotateLeft) { let left = initVector[rotateLeft] | 0; let right = initVector[2] | 0; for (let round = 0; round < 15; round++) { // Right rotation of key2 key2 = (key2 >>> rotateRight) | (key2 << 24); // Modular addition key2 = (key2 + key1) | 0; // XOR with constant + round key2 ^= right + 3328; // Left rotation of key1 key1 = (key1 << rotateLeft) | (key1 >>> 29); // Operations on left/right... left = (left >>> rotateRight) | (left << 24); left = (left + right) | 0; right = (right << rotateLeft) | (right >>> 29); left ^= round + 3328; right ^= left; key1 ^= key2; } // Output in big-endian (8 bytes) return [ (key1 >>> 24) & 255, (key1 >>> 16) & 255, (key1 >>> 8) & 255, key1 & 255, (key2 >>> 24) & 255, (key2 >>> 16) & 255, (key2 >>> 8) & 255, key2 & 255 ]; }

Pipeline de chiffrement Encryption Pipeline

Chaîne de traitement des données, de l'IV aléatoire à la compression finale.

Data processing chain, from random IV to final compression.

ko(4)
IV Aléatoire
J$(8,..)
Cipher ARX
Bytecode
Décrypté
Bn()
Mixage
PM()
Pack Message
Ub()
Compression
ko(4)
Random IV
J$(8,..)
ARX Cipher
Bytecode
Decrypted
Bn()
Mixing
PM()
Pack Message
Ub()
Compression

🔄 Rotation des constantes (découverte critique) 🔄 Constant Rotation (critical discovery)

Découverte majeure : La constante magique du cipher n'est pas fixe ! Elle change régulièrement avec chaque rotation du script. Cela rend obsolète toute tentative de contournement basée sur le reverse engineering d'une version antérieure.

Major finding: The cipher's magic constant is not fixed! It changes regularly with each script rotation. This makes any bypass attempt based on reverse engineering a previous version obsolete.

Timestamp Script Hash Constante magique Magic Constant
16:04:21Cp_4f0VEzU-X...1426
16:24:06V3ebOGDdmYS...3328
Rotation régulière du script Regular script rotation

Le script BotGuard est servi depuis une URL avec hash d'intégrité : //www.google.com/js/bg/{HASH}.js. Ce hash change régulièrement, invalidant le cache et forçant le téléchargement de la nouvelle version.

The BotGuard script is served from a URL with integrity hash: //www.google.com/js/bg/{HASH}.js. This hash changes regularly, invalidating cache and forcing download of the new version.

Endpoint WAA (Web Authentication API) WAA Endpoint (Web Authentication API)

Google expose BotGuard via un service gRPC-Web interne :

Google exposes BotGuard via an internal gRPC-Web service:

// Endpoint WAA POST https://waa-pa.clients6.google.com/$rpc/google.internal.waa.v1.Waa/Create Content-Type: application/json+protobuf // Structure de réponse [ ["bfkj", // Type null, [null, null, null, "//www.google.com/js/bg/{HASH}.js"], "{HASH}", // Hash du script "xJBElp...", // Bytecode challenge (base64) "botguard", // Nom du système null, "[null,null,null,...]" // Config initiale ] ]
// WAA Endpoint POST https://waa-pa.clients6.google.com/$rpc/google.internal.waa.v1.Waa/Create Content-Type: application/json+protobuf // Response structure [ ["bfkj", // Type null, [null, null, null, "//www.google.com/js/bg/{HASH}.js"], "{HASH}", // Script hash "xJBElp...", // Challenge bytecode (base64) "botguard", // System name null, "[null,null,null,...]" // Initial config ] ]

Patterns de Détection Detection Patterns

Signaux comportementaux analysés pour distinguer humains et bots.

Behavioral signals analyzed to distinguish humans from bots.

Analyse Comportementale Behavioral Analysis

Quatre catégories de comportements surveillés en temps réel.

Four categories of behaviors monitored in real-time.

🖱

Mouse Patterns

Trajectoire, vélocité, accélération, jitter. Un mouvement "parfait" (linéaire, vitesse constante) est suspect.

Trajectory, velocity, acceleration, jitter. A "perfect" movement (linear, constant speed) is suspicious.

Keyboard Patterns

Temps de pression (70-150ms normal), intervalle entre touches, taux d'erreurs, rythme de frappe.

Press duration (70-150ms normal), key intervals, error rate, typing rhythm.

📶

Scroll Patterns

Amplitude, direction, timing, fluidité. Un scroll par incréments fixes est suspect.

Amplitude, direction, timing, smoothness. Scrolling in fixed increments is suspicious.

Timing Analysis

Variance des intervalles, précision du timer, anomalies temporelles.

Interval variance, timer precision, temporal anomalies.

Éléments DOM Surveillés (100+) Monitored DOM Elements (100+)

Liste complète des 101 balises HTML trackées, extraite du code source.

Complete list of 101 tracked HTML tags, extracted from source code.

Structure : ARTICLE, SECTION, NAV, ASIDE, HEADER, FOOTER, MAIN, DIV

Structure: ARTICLE, SECTION, NAV, ASIDE, HEADER, FOOTER, MAIN, DIV

Headings : H1, H2, H3, H4, H5, H6, ADDRESS

Headings: H1, H2, H3, H4, H5, H6, ADDRESS

Texte : P, HR, PRE, BLOCKQUOTE, EM, STRONG, SMALL, S, CITE, Q, DFN, ABBR, DATA, TIME, CODE, VAR, SAMP, KBD, SUB, SUP, I, B, U, MARK, BDI, BDO, SPAN, BR, WBR, INS, DEL

Text: P, HR, PRE, BLOCKQUOTE, EM, STRONG, SMALL, S, CITE, Q, DFN, ABBR, DATA, TIME, CODE, VAR, SAMP, KBD, SUB, SUP, I, B, U, MARK, BDI, BDO, SPAN, BR, WBR, INS, DEL

Ruby : RUBY, RB, RT, RTC, RP

Ruby: RUBY, RB, RT, RTC, RP

Listes : OL, UL, LH, LI, DL, DT, DD

Lists: OL, UL, LH, LI, DL, DT, DD

Tableaux : TABLE, CAPTION, COLGROUP, COL, TBODY, THEAD, TFOOT, TR, TD, TH

Tables: TABLE, CAPTION, COLGROUP, COL, TBODY, THEAD, TFOOT, TR, TD, TH

Formulaires : SELECT, DATALIST, OPTGROUP, OPTION, OUTPUT, PROGRESS, METER, FIELDSET, LEGEND, BUTTON, INPUT (priorité haute)

Forms: SELECT, DATALIST, OPTGROUP, OPTION, OUTPUT, PROGRESS, METER, FIELDSET, LEGEND, BUTTON, INPUT (high priority)

Médias : FIGURE, FIGCAPTION, PICTURE, PARAM, TRACK, MAP, CANVAS

Media: FIGURE, FIGCAPTION, PICTURE, PARAM, TRACK, MAP, CANVAS

Interactif : DETAILS, SUMMARY, MENU, DIALOG, SLOT

Interactive: DETAILS, SUMMARY, MENU, DIALOG, SLOT

Obsolètes : FONT, CENTER, ACRONYM, BASEFONT, BIG, DIR, HGROUP, STRIKE, TT, NOBR (détection de tooling)

Obsolete: FONT, CENTER, ACRONYM, BASEFONT, BIG, DIR, HGROUP, STRIKE, TT, NOBR (tooling detection)

Types d'Événements Capturés Captured Event Types

Événements écoutés avec l'option {passive: true, capture: true}.

Events listened with {passive: true, capture: true} option.

Catégorie Category Événements Events Données collectées Collected Data
Mouse mousemove, mousedown, mouseup, click, dblclick Coordonnées, timing, bouton Coordinates, timing, button
Keyboard keydown, keyup, keypress Timing inter-touches, séquences Inter-key timing, sequences
Touch touchstart, touchend, touchmove Points de contact, pression Contact points, pressure
Scroll scroll, wheel Vélocité, direction, amplitude Velocity, direction, amplitude
Focus focus, blur, focusin, focusout Cible, durée Target, duration
Visibility visibilitychange document.hidden
DOM DOMContentLoaded, load Timing de chargement Load timing

Fingerprinting Environnemental Environmental Fingerprinting

Propriétés du navigateur et de l'environnement collectées pour créer une empreinte unique.

Browser and environment properties collected to create a unique fingerprint.

🌐 Navigator
  • userAgent
  • language / languages
  • platform
  • hardwareConcurrency
  • deviceMemory
  • maxTouchPoints
💻 Screen
  • width / height
  • availWidth / availHeight
  • colorDepth
  • pixelDepth
  • devicePixelRatio
Performance
  • performance.now()
  • performance.timeOrigin
  • timing.navigationStart
  • Jitter de timer (fluctuations) Timer jitter (fluctuations)
👁 Visibility
  • document.hidden
  • visibilityState
  • readyState
  • hasFocus()

Seuils de Détection Estimés Estimated Detection Thresholds

Valeurs limites déduites de l'analyse du code pour chaque métrique.

Threshold values inferred from code analysis for each metric.

Métrique Metric Valeur Normale Normal Value Seuil Bot Bot Threshold
Mouse velocity variance50-500< 10
Key press duration variance20-50ms< 5ms
Click interval variance100-1000ms< 20ms
Event count / second10-50> 200
Scroll delta variance20-100px< 5px

Détection WebDriver WebDriver Detection

Propriétés JavaScript vérifiées pour détecter Selenium, Puppeteer et autres outils.

JavaScript properties checked to detect Selenium, Puppeteer and other tools.

// Propriétés qui trahissent l'automatisation const WEBDRIVER_INDICATORS = [ 'navigator.webdriver', // true si automatisé 'window.chrome.runtime', // absent en headless 'window.cdc_adoQpoasnfa76pfcZLmcfl_', // signature ChromeDriver 'document.$cdc_asdjflasutopfhvcZLmcfl_', // autre signature CD '$chrome_asyncScriptInfo', // Puppeteer '__nightmare', // Nightmare.js '_phantom', // PhantomJS '__selenium_unwrapped', // Selenium '__webdriver_evaluate', // WebDriver ];
// Properties that betray automation const WEBDRIVER_INDICATORS = [ 'navigator.webdriver', // true if automated 'window.chrome.runtime', // absent in headless 'window.cdc_adoQpoasnfa76pfcZLmcfl_', // ChromeDriver signature 'document.$cdc_asdjflasutopfhvcZLmcfl_', // Another CD signature '$chrome_asyncScriptInfo', // Puppeteer '__nightmare', // Nightmare.js '_phantom', // PhantomJS '__selenium_unwrapped', // Selenium '__webdriver_evaluate', // WebDriver ];

Algorithme de Welford (implémenté) Welford Algorithm (implemented)

Méthode statistique pour calculer la variance en temps réel avec un minimum de mémoire.

Statistical method to calculate variance in real-time with minimal memory.

BotGuard utilise l'algorithme de Welford pour calculer la variance en ligne avec O(1) mémoire :

BotGuard uses the Welford algorithm to calculate online variance with O(1) memory:

class StatisticsCollector { constructor() { this.n = 0; // Nombre d'échantillons this.mean = 0; // Moyenne glissante this.m2 = 0; // Somme des écarts au carré } addSample(value) { this.n++; const delta = value - this.mean; this.mean += delta / this.n; this.m2 += delta * (value - this.mean); } get variance() { return this.n > 1 ? this.m2 / (this.n - 1) : 0; } }
class StatisticsCollector { constructor() { this.n = 0; // Sample count this.mean = 0; // Rolling mean this.m2 = 0; // Sum of squared deviations } addSample(value) { this.n++; const delta = value - this.mean; this.mean += delta / this.n; this.m2 += delta * (value - this.mean); } get variance() { return this.n > 1 ? this.m2 / (this.n - 1) : 0; } }

Code Source Déobfusqué Deobfuscated Source Code

Version reconstruite et commentée du script BotGuard v41 après déobfuscation.

Reconstructed and commented version of BotGuard v41 script after deobfuscation.

Note : Ce code est une reconstruction basée sur l'analyse statique. Les noms de fonctions et variables ont été renommés pour la lisibilité. Le code original utilise des identifiants obfusqués comme J$, mL, zV, etc.

Note: This code is a reconstruction based on static analysis. Function and variable names have been renamed for readability. The original code uses obfuscated identifiers like J$, mL, zV, etc.

Table de correspondance des identifiants Identifier Mapping Table

Correspondance entre les noms obfusqués et leur fonction réelle.

Mapping between obfuscated names and their actual function.

Obfusqué Obfuscated Fonction Function Description
J$ARX Cipher Chiffrement principal Main encryption
mLVM Loop Boucle principale VM Main VM loop
zVSetup Initialisation Initialization
EbencodeUTF8 Encodage UTF-8 UTF-8 encoding
Czbase64Url Encodage Base64 URL-safe URL-safe Base64 encoding
kogenerateIV Génération IV aléatoire Random IV generation
BnmixFunction Fonction de mélange ARX ARX mix function
PMpackMessage Empaquetage du message Message packing
sTarrayIndexOf Recherche dans tableau Array search

Types de Messages Internes Internal Message Types

Constantes utilisées pour la communication interne du système.

Constants used for internal system communication.

Constante Constant Type Description
GVINIT Initialisation du système System initialization
dFTOUCH_EVENT Événement tactile capturé Captured touch event
rFRESULT Résultat de traitement Processing result
akASYNC_CALLBACK Callback asynchrone Async callback
KdDOM_READY DOM chargé et prêt DOM loaded and ready
wFLOAD Chargement page Page loading
keUPDATE Mise à jour état State update
g0METRIC Métrique collectée Collected metric
XKEXECUTE Exécution bytecode Bytecode execution

Structure principale du code Main Code Structure

Code source reconstruit avec annotations explicatives.

Reconstructed source code with explanatory annotations.

/** * Google BotGuard v41 - Deobfuscated Structure * * Copyright Google LLC - Apache 2.0 License * Reconstructed for educational purposes */ var xo = xo || {}; xo.m = 41; // Version // Main namespace (function(Z) { Z.botguard || (Z.botguard = {}); // ═══════════════════════════════════════════════════════ // SECTION 1: Constants & Configuration // ═══════════════════════════════════════════════════════ const DOM_ELEMENTS = [ "ARTICLE", "SECTION", "NAV", "ASIDE", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER", "FOOTER", "ADDRESS", "P", "HR", "PRE", "BLOCKQUOTE", "OL", "UL", "LI", "DL", "DT", "DD", "FIGURE", "FIGCAPTION", "MAIN", "DIV", // ... 100+ elements total (101 extracted) "BUTTON", "INPUT" // High priority ]; const EVENT_OPTIONS = { passive: true, capture: true }; // ═══════════════════════════════════════════════════════ // SECTION 2: ARX Cipher (Speck-like) // ═══════════════════════════════════════════════════════ function arxCipher(data, key) { let left = data[0] | 0; let right = data[2] | 0; let key1 = key[0] | 0; let key2 = key[1] | 0; const MAGIC = 3328; // Rotates: 1426, 3328, ... for (let round = 0; round < 15; round++) { // Rotate right 8 bits key1 = (key1 >>> 8) | (key1 << 24); key1 = (key1 + left) | 0; key1 ^= right + MAGIC; // Rotate left 3 bits left = (left << 3) | (left >>> 29); left ^= round + MAGIC; right ^= left; key1 ^= key2; } return [ (key1 >>> 24) & 255, (key1 >>> 16) & 255, (key1 >>> 8) & 255, key1 & 255, (key2 >>> 24) & 255, (key2 >>> 16) & 255, (key2 >>> 8) & 255, key2 & 255 ]; } // ═══════════════════════════════════════════════════════ // SECTION 3: Statistics (Welford Algorithm) // ═══════════════════════════════════════════════════════ class StatisticsCollector { constructor() { this.n = 0; this.mean = 0; this.m2 = 0; } addSample(value) { this.n++; const delta = value - this.mean; this.mean += delta / this.n; this.m2 += delta * (value - this.mean); } get variance() { return this.n > 1 ? this.m2 / (this.n - 1) : 0; } get stdDev() { return Math.sqrt(this.variance); } } // Reservoir Sampling (50 samples) class ReservoirSampler { constructor(size = 50) { this.maxSize = size; this.samples = []; this.count = 0; } add(value) { this.count++; if (this.samples.length < this.maxSize) { this.samples.push(value); } else { const idx = Math.floor(Math.random() * this.count); if (idx < this.maxSize) { this.samples[idx] = value; } } } get median() { const sorted = [...this.samples].sort((a, b) => a - b); return sorted[sorted.length >> 1]; } } // ═══════════════════════════════════════════════════════ // SECTION 4: Virtual Machine // ═══════════════════════════════════════════════════════ class BotGuardVM { constructor(bytecode) { this.bytecode = bytecode; this.registers = new Array(512).fill(0); this.stack = []; this.ip = 0; // Instruction pointer } // Register indices static REG = { IP: 510, SP: 152, ERROR: 508, STATUS: 498, BUFFER: 468, OUTPUT: 302, INPUT: 256, METRICS: 130, KEY: 117, CRYPTO: 51 }; readBits(count) { // Variable-width bit reading let result = 0; for (let i = 0; i < count; i++) { const byteIdx = this.ip >> 3; const bitIdx = this.ip % 8; result |= ((this.bytecode[byteIdx] >> bitIdx) & 1) << i; this.ip++; } return result; } execute() { while (this.ip < this.bytecode.length * 8) { const opcode = this.readBits(8); this.executeOp(opcode); } } executeOp(op) { // Opcode handlers (simplified) switch(op) { case 0x01: this.opInit(); break; case 0x02: this.opMetrics(); break; case 0x03: this.opToken(); break; // ... more opcodes } } } // ═══════════════════════════════════════════════════════ // SECTION 5: Event Collection // ═══════════════════════════════════════════════════════ class EventCollector { constructor() { this.events = []; this.mouseStats = new StatisticsCollector(); this.keyStats = new StatisticsCollector(); this.lastTimestamp = 0; } attachListeners() { const opts = { passive: true, capture: true }; document.addEventListener('mousemove', e => { this.recordMouse(e); }, opts); document.addEventListener('keydown', e => { this.recordKey(e); }, opts); document.addEventListener('scroll', e => { this.recordScroll(e); }, opts); } recordMouse(e) { const now = performance.now(); const delta = now - this.lastTimestamp; this.mouseStats.addSample(delta); this.lastTimestamp = now; } } // ═══════════════════════════════════════════════════════ // SECTION 6: Token Generation // ═══════════════════════════════════════════════════════ function generateToken(metrics) { // 1. Serialize metrics to UTF-8 const encoded = encodeUTF8(metrics); // 2. Compress const compressed = compress(encoded); // 3. Encrypt with ARX cipher const iv = generateRandomIV(4); const encrypted = arxCipher(compressed, iv); // 4. Encode to base64url return '!' + base64urlEncode(encrypted); } function base64urlEncode(data) { let str = ''; for (let i = 0; i < data.length; i += 8192) { str += String.fromCharCode.apply(null, data.slice(i, i + 8192)); } return btoa(str) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); } // ═══════════════════════════════════════════════════════ // SECTION 7: Public API // ═══════════════════════════════════════════════════════ xo.bg = function(callback) { // Main entry point return new Promise((resolve) => { const collector = new EventCollector(); collector.attachListeners(); // Wait for DOM and generate token document.addEventListener('DOMContentLoaded', () => { const token = generateToken(collector); resolve(token); }); }); }; xo.a = function(challenge) { // Process challenge data return xo.bg(); }; xo.fcn_ = function(challenge, callback) { // Legacy interface xo.a(challenge).then(callback); }; })(window);

Télécharger le code source Download source code

Fichiers disponibles pour analyse approfondie.

Files available for in-depth analysis.

Avertissement : Ce document est à but éducatif uniquement. L'utilisation de ces informations pour contourner des mesures de sécurité peut violer les conditions d'utilisation des services concernés et potentiellement des lois sur la fraude informatique.

Warning: This document is for educational purposes only. Using this information to bypass security measures may violate the terms of service of the concerned services and potentially computer fraud laws.