Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
recaptcha — Документация и обратная разработка reCAPTCHA | Kitploit
Инструменты/GitHubGitHub/elyelysiox/recaptcha
Статический анализДинамический анализ кода (DAST)Обратная инженерияВеб-безопасностьАнти-БотОбход CAPTCHA
GitHubelyelysiox/recaptcha

recaptcha

Документация и обратная разработка reCAPTCHA

Репозиторий
22738332 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Описание

Этот репозиторий содержит технический анализ антибота Google (reCAPTCHA), сфокусированный на:

  • Структуре и значениях полезной нагрузки (Payload)
  • Техниках снятия отпечатков (Fingerprinting)
  • Техниках обфускации (Obfuscation)
  • Техниках анти-отладки/анти-модификации (Anti-debugging/Tampering)
  • Виртуальных машинах (Virtual Machines)

Контакты

  • Discord: @g_recaptcha
  • Telegram: @lyxlobyx

Техники обфускации

reCAPTCHA — одна из антибот-систем с наиболее изощрёнными техниками обфускации, применяющая ряд преобразований, которые делают код менее читаемым и усложняют обратную разработку. Большинство обфускаций легко обрабатываются с помощью абстрактного синтаксического дерева (AST), но некоторые выполняются во время выполнения, делая AST в этом случае бесполезным. К коду также применяется полиморфизм, изменяющий его структуру в каждой версии скрипта. Например, код не выполняет действие напрямую. Вместо этого используются объекты или функции, меняющие форму.

  • Последовательные выражения (Sequence Expressions) Код уплощается путём преобразования каждого блока инструкций в непрерывное выражение, разделённое запятыми; может встречаться в операторах if, аргументах функций и даже внутри объектов. seq

  • Смешанная булева арифметика (Mixed Boolean Arithmetic) Переплетает арифметические операции (сложение, вычитание, умножение) с побитовыми (AND, OR, XOR, NOT), чтобы скрыть исходную логику, например -2 * ~(h & H) + -2 + (h ^ H).

  • Косвенная таблица функций (Indirect Function Table) Каждая функция помещается в таблицу и вызывается по индексу, например functions[index](https://github.com/elyelysiox/recaptcha/blob/main/args).

  • Встроенный постоянный массив (Inline Constant Array) Литерал локального массива присваивается прямо внутри выражения; массив группирует константы (числа, строки), которые многократно используются в теле функции через доступ по индексу.

    // b = [14, 1, "call"] присвоено внутри последовательного выражения
    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
    }
    
  • Мультиплексирование функций (Function Multiplexing) Несколько логически различных функций объединяются в одну, используя числовой параметр как селектор блока. Активный блок определяется путём проверки параметра на побитовые условия. Вызывающие передают числовой литерал в качестве селектора.

    function(N, y, U, Y, h, H, m, C, u) {
        C = [26, 47, 6];
    
        // блок 1
        if ((N - 2 ^ 14) < N && (N - C[2] | 28) >= N) {
            // логика преобразования значения в строку
        }
    
        // блок 2
        if ((N + 4 & 40) >= N && (N + 5 & C[0]) < N) {
            Y = bB();
            throw Error(Y === void 0 ? "unexpected value " + U + y : Y);
        }
    
        return u;
    }
    
  • Ветвление через логические операторы (Logical Operator Branching) Заменяет блоки if и if/else на короткое замыкание логических операторов, превращая поток управления в выражения. В сочетании с последовательными выражениями множество ветвей выглядят как одно непрерывное выражение, разделённое запятыми.

    // if (a) { block }
    a && (block)
    
    // if (!a) { block }
    a || (block)
    
    // if (a) { x } else { y }
    a ? x : y
    
    // в сочетании с CFF и последовательными выражениями:
    (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), ...)),
    
  • Привязка нативных методов как констант (Bind Native Methods Constants) Привязывает нативные методы браузера к их исходным получателям, сохраняя их как константы для предотвращения модификации.

    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)
    
  • Мёртвый код (Dead Code) Недоступные или неиспользуемые блоки кода вставляются по всему файлу, увеличивая его размер до более чем 60 000 строк; это затрудняет статический анализ и обратную разработку с помощью LLM.

  • Уплощение потока управления (Control Flow Flattening) Преобразует каждую часть кода (объявления и циклы) в плоский конечный автомат. Скрывает исходную логику выполнения, направляя все блоки кода через центральный блок-диспетчер.

    Диспетчеры могут менять форму; некоторые имеют 2-3 переменных состояния, а тип цикла/условия меняется. Выглядят они так:

    cff1

    Это CFF с двумя переменными состояния: одна управляет блоком catch, другая — блоком try.

  • Зашифрованный пул строк (Encrypted String Pool) Все строковые литералы (DOM API, свойства браузера, CSS-значения, сообщения об ошибках и т.д.) зашифрованы в одном огромном пуле строк. Функция дешифрования использует seed и XOR-шифр на основе LCG для извлечения каждой строки во время выполнения.

    По всему коду разбросано более 1990 мест вызова; функция дешифрования использует нарастающий ключ, накапливающий декодированные кодовые точки, что делает каждый символ зависимым от всех предыдущих.

    X = function(J, b, P, F, U) {
        U = ["codePointAt", 127, "char encrypted pool"];
        for (F = (P = 0, b = "", l); P < Q; P++)
            J = (U[2][U[0]](c + P) ^ F) & U[1],  // XOR с нарастающим ключом
            b += String.fromCodePoint(J),
            F += J; // накопление ключа
        return G = b;
    }
    
    // места вызова передают seed для поиска и дешифровки каждой строки
    Z[23](64, 4, 54961, 103)()  // → "lang"
    Z[23](66, 4, 54961, 103)()  // → "addEventListener"
    Z[23](32, 12, 20287, 852)() // → "inline-block"
    

    decstrings

  • Итератор значений с состоянием (Stateful Value Iterator) reCAPTCHA использует функцию с состоянием, которая возвращает последовательность объектов и значений среды выполнения (например, window, document.body, числовые константы) в фиксированном порядке; каждый вызов сдвигает внутренний курсор; вызов не по порядку или слишком много раз портит все последующие чтения. Механизм тайм-аута аннулирует состояние через заданный интервал, возвращая null для любых поздних чтений.

    // последовательные вызовы возвращают разные значения:
    c()  // → window
    c()  // → document.body
    c()  // → 123
    c()  // → null (тайм-аут истёк)
    
    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  
    
  • Вычисляемая таблица функций (Computed Function Table) Похоже на Indirect Function Table, но здесь индекс получаемой функции вычисляется во время выполнения на основе seed с использованием XOR и Modulus.

    c = ((Q ^ no | U[1]) >> 5) + no
    A = mN[(c % U[2] + U[2]) % U[2]]  // mN — таблица функций (50+ функций)
    
    q[29](5, 6977)   // seed=6977  → индекс разрешается в функцию mN[X]
    q[29](53, 6187)  // seed=6187  → другой индекс, другая функция
    

    computed

Скачать инструмент