看了很多的破解滑动验证码,决定破解一下空间推理验证码。破解思路,通过分析接口请求,对图片物体进行定位分类,通过模拟请求破解验证码。
研究的网站为 https://www.geetest.com/show
一、register-space
获取gt(一般一个网站是固定的)、challenge(验证流水号,服务端 SDK 向极验服务器申请得到)参数。
challenge参数只能使用一次,一但后面get.php请求后就无法再请求,同时换ip的情况下也会失效。
二、黑色的三个请求只要根据他的参数照着模拟就可以了,不需要处理结果
第一次的get.php和ajax.php是无感验证,执行fullpage.js,收集浏览器信息,加密w参数直接填空就可以了。
三、红色的请求
https://api.geetest.com/get.php
获取图片和文字加密信息等
请求参数
is_next: true
type: click
gt: c9428d9361cd70d26e28d7cd780ec640
challenge: 263e2e11a85337b92d821c158c1b438f
lang: zh-cn
https: true
protocol: https://
offline: false
product: float
api_server: api.geetest.com
isPC: true
autoReset: true
width: 100%
callback: geetest_1644770447212
请求响应
响应中,pic,c,s这3个参数非常重要,在生成w加密参数是需要用到它们
"data": {
"theme": "silver",
"theme_version": "1.5.0",
"static_servers": ["static.geetest.com/", "dn-staticdown.qbox.me/"],
"api_server": "api.geetest.com",
"logo": false,
"sign": "\u8bf7_\u70b9\u51fb_\u5728\u5927\u578b\u7eff\u8272\u7403\u4f53\u540e\u9762\u7684\u7ea2\u8272\u7269\u4f53\u3002", # 物体的文字信息
"pic": "/nerualpic/space_l1_zh_2019.07.17/space/587417a058088f2f5934e22fcc503980.jpg", # 图片的url地址,同时也是后续加密生成w需要
"pic_type": "space",
"num": 0,
"c": [12, 58, 98, 36, 43, 95, 62, 15, 12], # 后续生成w需要
"s": "514c622c", # 后续加密生成w需要
······
}
点击坐标后提交,将坐标等信息加密在w中post给服务器,返回validate的值表示验证成功
https://api.geetest.com/ajax.php
请求参数
'gt': 'c9428d9361cd70d26e28d7cd780ec640',
'challenge': '263e2e11a85337b92d821c158c1b438f',
'lang': 'zh-cn',
'pt': 0',
'client_type': 'web',
'w': 'Y1gV9CACfWsfd)vtGUQD(WuKBZnmxhgfpXfD)qDHwhG(h1F4rOco··· //点击的坐标和一些信息的加密信息(点击坐标,图片pic,上面的c和s内容)
'callback': 'geetest_1644752017507'
请求响应
{
"status": "success",
"data": {
"result": "success",
"validate": "23ff2a4fddac68b9e40884befcfbb9af",
"score": "1"
}
}
有了validate就可以和gt,challenge一起提交给需要登录的网站接口做验证了。
破解的关键是获取加密参数生成方法。主要在click.3.0.2.js文件中,因此我们学习大佬分析AST的方法将他们反混淆,然后去分析debug。具体可以看看大佬的方法,我就不重复造轮子了。
JS逆向:AST还原极验混淆JS实战
将网站混淆过的源代码下载下来,格式化后将上面几个函数(内容也要的)拷贝到还原方法前,文件位置替换成下载下来的文件地址。运行就会生成反混淆的代码。
AtULc.BaI = function() {}();
AtULc.CJR = function() {}();
AtULc.Dvg = function() {};
AtULc.EyS = function() {};
function AtULc() {}
// 需要解码的文件位置
let encode_file = "click.3.0.2init.js"
// 解码后的文件位置
let decode_file = "click.3.0.2.js"
将代码反混淆后可以使用chrome的reres插件将原本混淆的代码替换
本地地址要加上file:/// ,同时要在管理reres插件的界面允许访问本地地址
源码我写下来放在github了 点击进入。同时因为不方便下载reres插件,我也将插件上传在github
替换文件后打开chrome的开发者工具,再sources中搜"w"
看d的其他参数,显然这个w就是这里产生的,打上断点去提交验证码
w是p+u,继续往上一步一步分析。
f = Q["encrypt"](de["stringify"](o), r["gCdf"]());
p = h["YQee"]( f);
u = r["fTbG"]();
1、参数 p 生成
f中有两个参数 de["stringify"](o) 和 r["gCdf"]()
一、de["stringify"](o)
de["stringify"](o) 中只有一个参数o,往上找o
var o = {
"lang": n["lang"] || "zh-cn",
"passtime": t,
"a": e,
"pic": n["pic"],
"tt": pe(s, n["c"], n["s"]),
"ep": r["eRts"]()
};
"lang": n["lang"] || "zh-cn" 默认等于"zh-cn"就行
"passtime": t 通过验证时间,随便多少都行888之类,或者就按你debug时的大小
"a": e e就是点击坐标,最小"0_0",最大"10000_10000",为xy的百分比
"pic": n["pic"] get.php响应中"pic"中内容
"tt": pe(s, n["c"], n["s"]) get.php响应中"c"和"s"的内容
"ep": r["eRts"]() 这个参数可以为空 令"ep"= {}
其中"tt": pe(s, n["c"], n["s"])
s 就在定义 o 的上方 s = r["NfwI"]["EhLr"]()
找到EhLr
所以s=e["Xkir"](e["BjJO"](t)
打印出 t 看看
可以看出就是鼠标移动点击的信息和时间,把chrome切换成手机调试模式
可以将鼠标操作缩短到
经过测试,这里面的点击坐标为页面的坐标,多少没有关系,保留即可,只要将其中的时间戳换成破解的时间。间隔的时间仿造图中时间差即可。至于能否更简洁更简单办法可以自己尝试一下。
将"Xkir""EhLr""BjJO"这些函数都掏出来,修修改改到把 t 传参进去得到 s
最后在从代码里扣出pe函数,把之前get.php响应中的 c 和 s 一起传入就得到了"tt"的值
二、r["gCdf"]()
找 gCdf 这个函数
t = ae()
继续把ae也扣下来,把他们一步步连起来来即可。
f = Q["encrypt"](de["stringify"](o), r["gCdf"]());
p = h["YQee"]( f);
2、参数 u 生成
u = r["fTbG"]()
可以看出用到了生成 p 时用到的gCdf
把 k 抠出来直接调用 gCdf就可以了
这样 w = p + u 就全部破解完了,可以参考下我上传在github上代码 点击进入