Todos os posts
5 min de leituraglizzykingdreko

Analisando as mudanças mais recentes do Datadome

De vez em quando o Datadome realmente implementa algo novo, e eu sempre torço por uma situação picante, mas essa (de novo) parece não ser o caso.

Analisando as mudanças mais recentes do Datadome

De vez em quando o Datadome realmente implementa algo novo, e eu sempre torço por uma situação picante, mas essa (de novo) parece não ser o caso.

Sem quebra-cabeça!

Vamos começar falando da ativação global (aparentemente) real do captcha noPuzzle

Isso fazia parte de um código adormecido colocado há um tempo, mas eu nunca tinha visto ele ativo antes de algumas semanas atrás.

No momento parece que o clássico "slide captcha" deles foi desativado globalmente (então provavelmente não é uma configuração por site).

Prós

Na prática, em termos de resolução, nada mudou, talvez até tenha melhorado, já que antes você tinha que calcular a localização de "chegada do slide" (para os movimentos e sinais), enquanto agora vai ser sempre um valor estático. O tempo de resolução também foi reduzido, já que não é mais necessário resolver e analisar as imagens do desafio.

Contras

Estou assumindo que isso significa que eles estão prestes a implementar um novo captcha baseado em imagem (torço por eles)

Máquina Virtual — plv3

Essa atualização veio acompanhada da implementação, tanto no captcha quanto no interstitial, do parâmetro plv3.

A geração dele é totalmente tratada pelo arquivo deles vm-obj.js.

Vou explicar essa parte da forma mais simples possível para que qualquer leitor entenda do que estamos falando.

O que é uma VM (Máquina Virtual) de Javascript?

Em poucas palavras, o Javascript normalmente roda no seu navegador graças à engine dele, capaz de entender especificamente Javascript.
Uma VM permite rodar outro código. Quase como um pequeno pc dentro da janela do seu navegador. Isso ajuda principalmente na proteção e ofuscação de código.

Agora que entendemos VMs em geral, vamos ver como o Datadome implementa a deles especificamente

A VM do Datadome

A lógica segue estes 3 passos:

┌─────────────────────────────────────────────────────────────┐
│                      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}           │
└─────────────────────────────────────────────────────────────┘

Essas instruções de bytecode vêm daquela string longa que encontramos dentro do arquivo deles vm-obj.js

Stack
A VM usa uma "stack" (pilha) onde você só pode fazer push ou pop pelo topo

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)
**O Program Counter diz à vm onde ler a próxima instrução

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)

Isso porque cada número no bytecode representa uma operação; na do Datadome vamos encontrar por volta de 100 delas diferentes:

| 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                |
| ...    | ...      | ...                            |

digamos que a VM queira verificar se o seu navigator tem uma certa característica; ela vai proceder mais ou menos assim:

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)

Os dados de saída

Após uma execução bem-sucedida da VM (por volta de 360k instruções para um captcha, cerca de 100k a menos para o desafio interstitial) a saída vai se parecer com:

{
  "r": "aGVsbG...",  # output fingerprint value
  "i": 340580,       # interactions done
  "t": 25            # elapsed time
}

Com esses dados de saída agora temos o r que será usado como nosso plv3, enquanto os outros 2 vão ser usados para o payload de sinais.

Como pode ser resolvido?

Atualmente as instruções de bytecode fazem várias verificações antes/durante a extração do fingerprint, que não só precisam bater com os detalhes do seu payload resolvido, mas também com os do desafio que você está resolvendo.

Isso significa que usar uma aba de navegador para resolver não é só a pior e menos escalável solução; também vai ser inviável. Então boa sorte às soluções baseadas em selenium por aí tentando lidar com isso.

A melhor abordagem, de fato, seria entender essas instruções, o que a VM está procurando e analisando, para então criar um ambiente baseado em script capaz de rodar corretamente o arquivo com os mesmos detalhes usados nas construções do payload de sinais.

A chave principal na engenharia reversa de antibots é sempre: "ter uma noção do que está acontecendo" ou você vai pagar o preço por isso depois!

Estou assumindo que isso é só um primeiro teste do Datadome; vamos ver se as próximas mudanças na VM vão ser realmente fortes lol

Precisa de uma solução estável para o Datadome?

Entre em contato com especialistas que realmente entendem a tecnologia; você não quer ver o seu projeto caindo toda vez que o Datadome empurra uma mudança.

Na TakionAPI nós fornecemos isso. Dê uma olhada, comece um teste gratuito e depois confira a nossa documentação; uma chamada de API e o Datadome deixa de ser um problema com que você precise se preocupar.

Conecte-se comigo

Se você gostou deste artigo, me siga no GitHub e no Medium para receber notificações sempre que eu postar ou abrir o código de algo.

web-scrapinganti-botreverse-engineeringjavscript-vmdatadome

Pule a engenharia reversa.

O Takion retorna cookies, headers e tokens novos para cada grande muro antibot. Um POST, sem navegador, primeira chamada em menos de uma hora.