Разбираем последние изменения Datadome
Время от времени Datadome действительно выкатывает что-то новое, и я каждый раз надеюсь наткнуться на что-нибудь горячее, но и на этот раз (снова) всё,…

Время от времени Datadome действительно выкатывает что-то новое, и я каждый раз надеюсь наткнуться на что-нибудь горячее, но и на этот раз (снова) всё, похоже, не так.

No puzzle!
Начнём с того, что, похоже, глобально включили noPuzzle captcha.
Это был кусок «спящего» кода, заложенного довольно давно, но в активном состоянии я его ни разу не видел вплоть до пары недель назад.
Сейчас, судя по всему, их классическая «slide captcha» глобально отключена (то есть это, скорее всего, не настройка на уровне конкретного сайта).
Плюсы
По факту в плане решения ничего не изменилось, а может, даже стало лучше: раньше нужно было вычислять точку «прибытия слайдера» (для движений и сигналов), а теперь это всегда статичное значение. Время решения тоже сократилось, поскольку больше не нужно решать и анализировать изображения проверки.
Минусы
Я предполагаю, что это означает, что они вот-вот выкатят новую captcha на основе изображений (надеюсь для них, что так).
Виртуальная машина — plv3
За этим обновлением последовало внедрение параметра plv3 как в captcha, так и в interstitial.

Его генерация полностью реализована в их файле vm-obj.js.

Я постараюсь объяснить эту часть максимально просто, чтобы любой читатель понял, о чём вообще речь.
Что такое Javascript VM (виртуальная машина)?
В двух словах: обычно Javascript выполняется в вашем браузере благодаря его движку, который умеет понимать именно Javascript.
VM же позволяет выполнять другой код. Почти как маленький компьютер внутри окна вашего браузера. В основном это помогает с защитой и обфускацией кода.
Теперь, когда мы в общих чертах разобрались с VM, посмотрим, как именно свою реализует Datadome.
VM у Datadome
Логика состоит из этих 3 шагов:
┌─────────────────────────────────────────────────────────────┐
│ BYTECODE │
│ (A long string of numbers - the encoded instructions) │
│ Example: [45, 128, 67, 23, 199, 54, 12, 88, ...] │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ THE VM ENGINE │
│ - Reads bytecode one instruction at a time │
│ - Has a "stack" to store temporary values │
│ - Has a "program counter" to track current position │
│ - Executes ~100 different operation types │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ OUTPUT │
│ A "fingerprint" - a unique signature of your browser │
│ Example: {"r": "abc123...", "i": 340000, "t": 25} │
└─────────────────────────────────────────────────────────────┘
Эти инструкции байткода берутся из той длинной строки, которую можно найти внутри их файла vm-obj.js.
Stack
VM использует «стек», из которого можно только push-ить значение на вершину или pop-ить с неё.
PUSH 5 → [5]
PUSH 3 → [5, 3]
ADD → [8] (pops 5 and 3, pushes their sum)
PUSH 2 → [8, 2]
MULTIPLY → [16]
**Program Counter (PC)
**Program Counter указывает VM, откуда читать следующую инструкцию.
Bytecode: [PUSH, 5, PUSH, 3, ADD, PUSH, 2, MULTIPLY]
↑
PC = 0 (start here)
After PUSH 5:
Bytecode: [PUSH, 5, PUSH, 3, ADD, PUSH, 2, MULTIPLY]
↑
PC = 2 (moved forward)
Так происходит потому, что каждое число в байткоде обозначает операцию, и в случае Datadome мы найдём около 100 различных:
| Opcode | Name | What it does |
|--------|----------|--------------------------------|
| 45 | PUSH | Put a value on the stack |
| 67 | ADD | Add two numbers |
| 89 | JUMP | Go to a different position |
| 92 | JUMP_IF | Jump only if condition is true |
| 23 | GET_PROP | Get a property from an object |
| 54 | CALL | Call a function |
| ... | ... | ... |
Допустим, VM хочет проверить, есть ли у вашего navigator определённая возможность — тогда она поступит примерно так:
Bytecode: [GET_WINDOW, GET_PROP, "navigator", GET_PROP, "userAgent", STORE]
Step 1: GET_WINDOW
Stack: [window]
(Gets the browser's window object)
Step 2: GET_PROP "navigator"
Stack: [navigator]
(Gets window.navigator)
Step 3: GET_PROP "userAgent"
Stack: ["Mozilla/5.0 Chrome/120..."]
(Gets the browser's user agent string)
Step 4: STORE
Stack: []
(Saves this value to use in the fingerprint)
Выходные данные
После успешного выполнения VM (порядка 360k инструкций для captcha и примерно на 100k меньше для interstitial-проверки) вывод будет выглядеть так:
{
"r": "aGVsbG...", # output fingerprint value
"i": 340580, # interactions done
"t": 25 # elapsed time
}
С этими выходными данными у нас теперь есть r, который будет использоваться как наш plv3, а два других пойдут в payload сигналов.
Как это можно решить?
Сейчас инструкции байткода выполняют несколько проверок до и во время извлечения fingerprint, и они должны совпадать не только с деталями вашего решённого payload, но и с деталями проверки, которую вы решаете.
Это значит, что использование вкладки браузера для решения — не просто худший и немасштабируемый вариант, но ещё и неработающий. Так что удачи всем ходящим вокруг решениям на базе selenium.
По-настоящему лучший подход — разобраться в этих инструкциях, понять, что VM ищет и анализирует, чтобы затем создать окружение на основе скрипта, способное корректно выполнить файл с теми же деталями, что используются при формировании payload сигналов.
Главный принцип в реверс-инжиниринге антиботов всегда один: «понимай, что происходит», иначе позже заплатишь за это цену!
Я предполагаю, что для Datadome это лишь первый тест — посмотрим, будут ли предстоящие изменения VM действительно сильными, лол.
Нужно стабильное решение для Datadome?
Свяжитесь с экспертами, которые действительно понимают технологию, — вряд ли вам хочется, чтобы ваш проект ложился каждый раз, когда Datadome выкатывает изменение.

В TakionAPI мы это предоставляем. Обязательно загляните, начните бесплатный доступ а затем изучите нашу документацию: один вызов api — и Datadome больше не проблема, о которой стоит беспокоиться.
Свяжитесь со мной
Если вам понравилась эта статья, подписывайтесь на меня в GitHub и на Medium, чтобы получать уведомления каждый раз, когда я что-то публикую или выкладываю в open source.
Пропустите реверс-инжиниринг.
Takion возвращает свежие cookie, заголовки и токены для любой крупной антибот-стены. Один POST, без браузера, первый вызов в течение часа.