某易易盾验证码处理思路(下)

本文章只做技术探讨, 请勿用于非法用途。

目标网站

继续来说易盾, 这次来聊验证接口。配合上期的获取图片接口, 可以实现无感过易盾验证码。

接口分析

还是先来看接口, 可以通过多次尝试滑动来观察不同的情况。

Json 复制代码
// 目标接口
https://c.dun.163.com/api/v3/check 
// 核心参数
{
    "id": "07e2387ab53a4d6f930b8d9a9be71bdf", // 绑定浏览器, 定值
    "token": "7bbb4243ed7e4c2a9071ea549e2ffce9", // 获取验证码图片时一并返回
    "data": {"d":"Mu5sTZnRyggS6kmLW2mk94Y6KppHjjCHlqZFidiesQ.+Upkz9OZUAWjRnJBXGCgDWDiFC20MRnuryh5.YTbBXCWssqOythtza1IjxnTdzSIsLDkXOeIh+LOiBZu9+MOaSchEicLO8mZWdgVqxRgqoqbR0kvFpY.CjsWDA/9pz+9uyeHgof30DRDGUqi.WxihlSTu5QxjDpS9/2OnSIKGX0dQDO16DIg06gbZMp9uvQ6kCkHwjythhNYyGesLJXGXeyeUX+yRa6sJ2jdAL+1LDYj4L+Ou6UxrJpAzJA09DIG8Gk96+O/KxkVz0puBzlrczdAc4NGrx2s4/.Qutp9pIcNZ5WLKJEJuESnZ9JNvj4jhzoNAQZabPkZWwFhtbcltMCQa0.qP6LXcx+KcDqf8XJXwAtH06NUMuMRSjUalwsBWOZHdcx0Twcy1h0hCif/8X8JpbW+Bzzyk4hlKyrJKjGpfKqaATT2ivF3nXXroqQtSm9LHNwzsRPtbS+wqB2oRv++m06a0A6fiahyq5NNvk.PPL8Y0o5IyU4an.WpNAsvd84dcL34OSapB8mSqUNwmrklRFVyDym/5gNgvLBJupZLTR5wBFe/u4K/BJIvdTK5lzGdRcsdMcaJjh62ZFnkHKMzeboeHm5iQjyJFEiI5E0boTapR4mXAE99nvOLagZXRrUgclduwUlbJ/oHbl1+gOY3M+9na/WQcgj.32pyOKeVaLXvdMj.CKcIFCbQTHlsLHjCZhaRawDEV4NaZTdEk0mnLam5y5OWn5ovXL2SvkXrhi5LSgS4.F5fc40F5c3aU22xHnIEPkidUqTiiI2gZ8PUDlmaVVZrxEmEumZI3IVQ8mwPa2MK+gjAfiJN4yvfVQRV24Qh0JVpnvkYemMHEWKnRw6I1okRcqdKcaZeZ4KTYjrtajEOpXtegM1cazv.hHYgZMFJOfxGcLEX34VdRCsUH8+jJQ.REF8FFygqy2raffQEYVOeClvdsZ041c4GFyjaBRNb6tPNlDwXiTIsTYGysiQ2ehE3yycWR4gtPFRHuXC1HyGzeJ6FUbFk/sAa/Dr9atNZ4rQAzgPbQhrU08DuUnJZhHoxu5.Lvg/FxE5ijhPjlHthGVL3oRth50NqvGTsi4nsKtmgdAJYPxAliPF3FIlCuZ6PxO/hT9rmGzt8YS5wR9npKqao3is+XXa6XpWKs","m":"","p":"NEsSFPLKeiEXrLWYGTkOptXmK9CyI6zUMvR6zz+wGsKvnq264nb4baMzjtgNeAuiaqIQ.B1IX6lyDpLuZeeJeVAnZ/f7","f":"nKJyVUdFfjYzHB/sVtUFHPzQTxfM+9lGmUbabsSwRQphN+ENG/krDnNWg1eIc15spqSa2V2sLI6AmbVXiNfSNuf+wuXU3G1WKBrStCCoYJsKBvzQHoFfXRgY5gdN56aVYLJ68JAedkTae/8L5+oElwlFThCb4g.zsJdKoPbyzuSbL5ifo65alWLTkcBMloa+VXG9.ipc2O.RZHJvg8k6MOhCPGCpMpvbgpEbR61qu195zqy.bnwfqdG141YPFBgdy4JnTr8f5Ky4CXxLfPa2gGu0pm5SWZ06Cd6q4Lz0qGKsT+teyHscIsQBwCPeQPE0JKDa3f9Lr9dOgrAoKSDvvYMj4uOwn2x3ja/2bJVrb59eTTexRyXxL0d2D3JzeQ8HoEnrs.6vP5dJXhqqaNj+l.3aIN.mqvuB9GJpTxB2e29CyNZDAclCK4JuDpseQPmP4amh0E5Ujw0MEDLwrkl6D4urSJjQymtA/E3sh0kxIA19RZRzAAFUIrRPvtXYPDl4j8ZsQX77","ext":".ggcbmz4wXbCi8yOeGA.AX4IwfM5X/ri2OhsHL.qYgkgdDM+P+rxl8fbaUISkcTXpbvYtD580GZQzWA2XCdebcMdbEs7"}, // 滑动轨迹信息, 需逆向参数
    "cb": "D3B6.KV5scsTxCUi8zuLDb6LuonP3gDhvuetYX%2BF9yR6tCbxWngKY4GV%2F89pVnvjO0ksKRMPGtDnJOIumJirnlNFT%2FE7", // 浏览器指纹, 上期有讲
}
// 响应 A, 参数校验失败
{
    "error": 100,
    "msg":"param check error"
}
// 响应 B, 轨迹校验失败
{
    "data": {
        "result": false,
        "zoneId": "CN31",
        "token": "4e5d5080835643bd9e0335d8264cea63",
        "validate": ""
    },
    "error": 0,
    "msg": "ok"
}
// 响应 C, 校验成功
{
    "data": {
        "result": true,
        "zoneId": "CN31",
        "token": "a5168f8f8edf432b890886968a363f24",
        "validate": "8gxMgwjCs36ABQyKiWXApPYj4qmeePZtNacdk+33/pWyyVk9xmp6Fe6etQ75HC/G/p4SqUksSPlt8+SstaDC3Eve43eTujSRtRjRkjwxQHqabY3Yt/dLHI1eYxltI8ofBf09ykmqlvr5T34qcjkDRQdIVobyM0ejR6jtvIPPQ8U="
    },
    "error": 0,
    "msg": "ok"
}

本文重点在于逆向部分, 能拿到响应 B 或是响应 C 即认为成功, 轨迹校验可以自己设计算法或是训练大模型来处理。

由上信息可知, data 就是我们需要逆向分析的参数。

加密分析

还是老方法, 先尝试全局搜索参数。因为 data 字段在响应中会出现, 导致会干扰搜索结果, 这里尝试搜索了 data 中的字段 ext , 将所有出现的位置都打上断点。

搜索结果示例

断点位置示例

变量值示例

分析断点处代码, 会发现这是一个 mouseUp 的监听事件, 也就是说在我们鼠标抬起时出触发的事件。他通过对 this["traceDta"]、this["atomTraceData"]、token 等变量处理来得到最终的 data 值, 通过查看我们基本可以确定这两个数组就是我们的轨迹内容, 接下来就是确定如何生成两个数组。

按照正常的思路, 我们应该继续往上找堆栈, 来查看 this 的指向。但是继续下去会发现上层的 this 指向是 document 对象, 和这里的 this 是不同的, 也就是说在事件函数中, 有哪里统一改变了 this 的指向问题。 只能改变方法, 尝试搜索 atomTraceData 和 a0_0x1e60(0x2d5)(atomTraceData 的加密值) 两个变量, 看看能不能找到他们生成的位置。

atomTraceData 定位示例

最终我们可以追到图中所示的地方, 可以看到这里是一个 mouseMove 事件, 监听鼠标的移动。这里向 atomTraceData 中 push 了一个数组 _0x1d0d76, 根据代码分析可以知道 _0x1d0d76 的内容为 [x轴偏移量, y轴偏移量, 耗费时间(毫秒), isTrust参数(恒定为 1)]。

traceData 加密示例

traceData 加密函数

继续分析, 可以知道, traceData 的值是通过 atmosTraceData 中的数组以及 token 值经过 _0x564a9f 函数加密得到。到此, 我们基本可以确定接下来的处理思路了。

  1. 自己设计算法生成 atmosTraceData 轨迹数组。
  2. 根据 atmosTraceData 调用加密函数生成对应的 traceData。
  3. 调用 mouseUp 函数, 传入两个数组, 获得最终的 data 值。

在开始之前, 还要做一些准备工作, 就是要把加密函数 _0x564a9f 以及 mouseUp 函数给抠出来到我们本地用。

加密函数全局化

加密函数测试

函数逻辑还是在 webpack 中, 位于第 8 个参数函数内, 跟之前的做法一样, 首先将其全局化, 拿到加密结果就算成功。

mouseUp 位置示例

mouseUp 处理

mouseUp 函数在第 36 个参数函数中的一个临时变量中, 无法直接获取, 所以我选择把他先赋值给一个变量, 然后再把变量全局化。

函数处理示例

该函数之前通过调用 this 中的值来计算, 现在我们改为传入数组参数, 所以要对代码做一些改动, 同时删掉一些和加密无关的兼容代码。

加密结果示例

开整

本地化

本地化代码示例

结合上期内容, 按照分析中的内容改动, 然后抽出来三个函数。

补环境

目前来看, 不需要额外的环境, 上期的环境可以通用。

请求

Python + subprocess

Python 代码示例

调用结果示例

补充点

  • 说一下验证码识别的问题, 可以用打码平台, 可以训练大模型, 不想费事的话用 ddddocr 这个库也可以的(对这个验证码来说准确度很高), 还有一点就是, 滑块的初始位置就有 10px, 计算的时候记得加上。
  • 滑动轨迹, 模拟的时候可以在 push 那个位置加上一个日志断点, 看看正常浏览器采集的数据是怎么样的作为参考。
  • 有大佬愿意的话, 可以分享一下自己的轨迹算法。

总结

啰哩啰嗦的, 总算是把这个说完了。

网站不能说复杂, 但是要关注的点确实很多, 如果不是跟着做的话, 可能会不知道再说什么。 比起来应该是没抖音、小红书那两期说的清楚, 不过确实没办法。

有问题的话私信我吧。

请洒潘江,各倾陆海云尔。

相关推荐
I'm Jie3 小时前
深入了解 Vue 3 组件间通信机制
前端·javascript·vue.js
用户90443816324604 小时前
90%前端都踩过的JS内存黑洞:从《你不知道的JavaScript》解锁底层逻辑与避坑指南
前端·javascript·面试
PPPPickup5 小时前
easychat项目复盘---获取联系人列表,联系人详细,删除拉黑联系人
java·前端·javascript
老前端的功夫5 小时前
前端高可靠架构:医疗级Web应用的实时通信设计与实践
前端·javascript·vue.js·ubuntu·架构·前端框架
脾气有点小暴6 小时前
前端页面跳转的核心区别与实战指南
开发语言·前端·javascript
San30.7 小时前
深入 JavaScript 内存机制:从栈与堆到闭包的底层原理
开发语言·javascript·udp
Fantastic_sj7 小时前
Vue3相比Vue2的改进之处
前端·javascript·vue.js
ttod_qzstudio9 小时前
深入理解 TypeScript 数组的 find 与 filter 方法:精准查找的艺术
javascript·typescript·filter·find
冬男zdn9 小时前
优雅处理数组的几个实用方法
前端·javascript
克喵的水银蛇10 小时前
Flutter 通用标签选择组件:TagSelector 支持单选 / 多选
javascript·windows·flutter