本文章只做技术探讨, 请勿用于非法用途。
目标网站
来聊聊某易易盾的验证码, 主要分为获取验证码图片和滑动接口两部分。因为篇幅较长, 分两次来聊。
这次先聊获取图片的接口, 通过页面加载或者刷新图片就可以看到, 链接如下。c.dun.163.com/api/v3/get
网站分析
接口分析
通过刷新网站, 多次观察接口顺序以及可以使用 Postman 等模拟请求的工具, 可以得到如下信息。
// 获取 dt 参数
https://c.dun.163.com/api/v2/getconf
// 获取验证码缺口及背景图片
https://c.dun.163.com/api/v3/get
// 重要参数(一些常规参数不再列出)
{
"id": "07e2387ab53a4d6f930b8d9a9be71bdf", // 每个浏览器应该是默认一个, 固定值
"iv": 4, // 定值
"token": "e6b3760268bb4c45aaf5bd4bc203ee4c", // 上次获取图片时一同返回, 首次获取可以传空
"dt": "UA753qUMw9tBAgVUEQfX2EE3mcTrQ2vI", // 通过上边接口获得, 不传不影响获取图片
"cb": "eqzH33i36v2Zyq.e4dOksKObgNMZc6hLfeAVVxEBRsFGR66c/kjbDCdTTTR4FYOOU2LQUE+WdERq0r1KW.yTmNYt6Sg7", // 加密参数
"fp": "ggAOP9HnqBlK\\SnKweEDDTz28Mt+kZyyWpizmc4IW2LsANsiLpdB5Iw0ZovpgvCA7n3Y6rmSY+iIb3t5RuaZmgLo2uj4zQdihK2v8rVE+L8X1CiGBuUIGNjTp\\/SkXGsfgoajd6c72Cj6jho\\jDpbffnWvTdNdiPHmQJ8YoXN+B4brtI:1761206077129", // 加密参数
}
也即是说, fp 和 cb 为这次需要逆向处理的参数。
加密分析
cb 参数
还是和之前一样, 首先全局搜索关键参数, 看看什么情况。
搜索关键词示例
一共五个地方出现该参数, 依次打上断点, 重新获取图片再次触发请求。
定位加密函数
在最终断点断到的位置, 可以看到 cb 参数是由 _0x62692 函数加密得到。同时也看到了 fp 参数的情况, 也方便了后续分析。
继续说 cb 参数, 进入到函数里边, 跟到函数执行的位置。
加密函数示例
加密函数文件结构示例
可以看到整体是一个 webpack 的结构, 可以把整个代码复制到本地编辑器中, 把无关的函数收缩起来, 定位一下我们需要的函数所在位置。
目标函数具体位置分析
分析结构后可以发现, _0x62692 这个函数是在第 71 个参数函数中定义的子函数。根据我们处理 webpack 的思路, 我们找到加载器函数, 加载第 71 个函数, 同时在里边定义子函数的位置把 _0x62692 暴露到全局供我们使用。
可以新打开一个干净的浏览器环境来验证下我们的思路是否可行。
加载器暴露示例
加密函数暴露示例
加密结果示例
成功得到 cb 参数加密结果, 按照同样的方式来找 fp 参数。
fp 参数
先回到最开始的位置, 对 fp 的堆栈进行跟值, 确定它在什么位置生成。
加密情况分析
依次向上翻堆栈, 直至找到值生成时候的位置。
跟值情况一
跟值情况二
到这里可以发现, 这个 this 是通过上层函数的参数赋予的, 所以要重新把断点打在上层函数上再继续跟。
但是这里重新下断点之后, 会发现刷新图片无法成功断到。可以猜测 fp 参数计算逻辑是在页面刷新的时候触发的, 所以可以尝试刷新页面。
这里解释一个情况, 刷新后可能会发现断点全部消失了。仔细观察的话, 会发现加密文件的名称其实有一直在变化(看起来是通过定时器实现的, 调试时间过长就让文件的参数加一这样), 重新加载了新文件导致旧断点消失。可以通过抓包工具来直接替换文件, 或者消失后重新再打一次断点就行。
更新断点
跟值情况三
一直跟值, 直到最终确定我们需要的值是在 window['gdxidpyhxde'] 中获取的。
接下来, 我们就需要监控 window 中的 gdxidpyhxde 对象, 看他的值是什么时候改变的, 继续定位真正的加密位置。可以用 油猴 插件, 来进行监控。
hook监控示例
fp生成位置定位
找到这里基本就结束了, 该文件还是在刚才的 webpack 中, 是在第 58 个参数函数中定义的子函数, 处理思路和刚才一样, 暴露一个 window.0x4407a8 出来。
加密结果示例
然后就是搬代码到复现了。
开整
本地化
还是刚才的东西, 把两个参数整合一下, 统一加载调用。
补环境
没啥说的, 正常用代理吐就行。
检查的环境不多。
请求
Python + execjs。
Python 部分示例
请求结果示例
总结
有两个参数, 想尽可能的说的清楚些, 所以可能有点啰哩啰嗦的。
有哪里不太清楚的可以私信问我, 我尽可能解答。
长时间不请求的话, 只传这几个参数好像有时候会失败。把浏览器的参数补齐就能正常拿到数据, 懒得测需要具体补哪些了。
请洒潘江,各倾陆海云尔。