全部文章
2 分钟阅读glizzykingdreko

分析 Datadome 的最新变化

Datadome 偶尔才会真正上点新东西,我每次都盼着能碰上点刺激的局面,但这次(又一次)好像并非如此。

分析 Datadome 的最新变化

Datadome 偶尔才会真正上点新东西,我每次都盼着能碰上点刺激的局面,但这次(又一次)好像并非如此。

没有拼图了!

先来聊聊 noPuzzle 验证码这次看起来是全局启用了。

这其实是一段很久以前就埋下的"沉睡代码",但直到几周前我才第一次真正看到它被激活。

目前看来,他们经典的"滑块验证码"已经被全局停用了(所以这大概不是按网站配置的)。

好处

其实从解决的角度看什么都没变,甚至可能还更好了,因为你以前得计算"滑块到达"的位置(用于生成移动轨迹和信号),而现在它永远是一个固定值。解决耗时也缩短了,因为不再需要去解算和分析挑战图片了。

坏处

我猜这意味着他们快要上一个新的、基于图片的验证码了(我倒是希望他们能上)。

虚拟机 —— plv3

这次更新之后,验证码和拦截页上都跟着上了 plv3 这个参数。

它的生成完全由他们的 vm-obj.js 文件负责。

接下来这部分我会尽量用最简单的方式讲清楚,好让任何读者都能明白我们在说什么。

什么是 JavaScript VM(虚拟机)?

简单说,JavaScript 平时能在你的浏览器里运行,靠的是浏览器的引擎,它专门能看懂 JavaScript。
而 VM 让你能运行别的代码,几乎就像是在你的浏览器窗口里塞了一台小电脑。这主要用于代码保护和混淆。

现在我们大致理解了 VM,接下来看看 Datadome 具体是怎么实现他们那套的。

Datadome 的 VM

它的逻辑遵循这 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]

**程序计数器(PC)
**程序计数器告诉 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 成功执行完之后(验证码大约是 36 万条指令,拦截页挑战大约少 10 万条),输出会长成这样:

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

有了这份输出数据,我们现在就有了 r,它会被用作我们的 plv3,而另外两个则会用于 signals payload。

怎么解决?

目前这些字节码指令会在指纹提取之前/期间做若干次检查,它们不仅需要匹配你所解出的 payload 的细节,还要匹配你正在解决的那个挑战的细节。

这意味着用一个浏览器标签页去解它,不仅是最糟糕、最没法扩展的方案,而且根本就跑不通。所以祝那些基于 selenium 的现成方案好运了。

真正最好的做法,是搞懂这些指令、弄清 VM 在找什么、在分析什么,然后创建一个基于脚本的环境,能用与构造 signals payload 时相同的细节正确地运行这个文件。

逆向反机器人最核心的一点永远是:"对正在发生的事有个数",否则以后你会为此付出代价!

我猜这只是 Datadome 的第一次试水,让我们看看接下来的 VM 变化到底会不会硬核吧,哈哈。

需要一个稳定的 Datadome 方案?

去联系那些真正懂这项技术的专家吧,你总不想每次 Datadome 推个改动,你的项目就跟着趴窝。

TakionAPI 我们就提供这个,一定去看看,开始免费试用,然后去看看我们的文档,一次 API 调用,Datadome 就不再是你需要操心的问题了。

与我联系

如果你喜欢这篇文章,在 GitHub 和 Medium 上关注我,每当我发帖或开源什么东西时你都会收到通知。

web-scrapinganti-botreverse-engineeringjavscript-vmdatadome

跳过逆向工程。

Takion 为每一道主流反机器人防护墙返回新鲜的 cookie、请求头和令牌。一次 POST,无需浏览器,一小时内完成首次调用。