作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
目标网站:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vYWRhcHRpdmUtY2FwdGNoYS1kZW1v
1 分析数据接口
通过抓包可知,页面加载时会先返回一个load包,返回的结果中包含滑块背景图和缺口图,还包含第二次请求所需的参数。
多次滑动滑块,发现第二次请求的包为verify包。
确定接口为load包和verify包。
2 分析参数
2.1 分析load包
分析发现load包的headers中不含参数加密,只在params中有参数加密,直接复制params中的参数进行请求,发现可以请求成功。(注意:这是第一个load包,所以不含其他加密参数。)
2.2 分析verify包
查看发现verify包中lot_number,payload,process_token参数均包含在load包的返回中,所以只需得到w参数,就可请求成功。
3 处理load包的返回结果
直接请求后得到结果,利用正则表达提取所需信息:
匹配结果如下:
4 逆向参数w
4.1 请求图片并识别
直接请求图片,利用ddddocr库识别缺口,返回坐标:
4.2 分析w参数
4.2.1 跟栈,找到w的生成位置
发现i即为参数w,在此处i被引用,往上查找。
var i = (0,m[$_BIBDO(91)])(f[$_BIBDO(91)][$_BIBDO(540)](e), n)
发现i的赋值地点,观察代码发现i是由一个函数 m[$_BIBDO(91)] 传入了两个参数f[$_BIBDO(91)][$_BIBDO(540)](e), n 后得到的结果。
断点断住,查看m[$_BIBDO(91)]
进入函数,发现该函数返回的为即为w。
return (0,d[$_DAECn(170)])(u) + _; //d[$_DAECn(170)]同下文中的g[$_DAEDN(162)]
查看代码,需要得到参数_、参数u和函数d[$_DAECn(170)](同下文中的g[$_DAEDN(162)])才能返回正确的加密内容。
4.2.2 逆向参数_
n为随机字符串,可以写死,在求参数u时也需要用到n。
跟进参数_,发现r[a][$_DAECn(903)]是一个对象,$_DAECn(971)为字符串'encrypt',所以参数_的生成逻辑是将n传入一个加密函数中返回的值。
跟进函数,发现有很多模块,直接把外层的大函数i扣下来
直接扣下来运行,报错,全局搜索,发现是参数生成的位置在一个自执行函数内,报错参数在自执行函数之前定义,直接把前面几个函数都扣下来
再次运行,报window错误,补上window,运行脚本,报出 navigator[$_DDADH(192)]未定义,全局搜索 navigator[$_DDADH(192)],打上断点,重新刷新页面( navigator[$_DDADH(192)]为页面加载一开始就生成,移动滑块无法断住),在断点处断住后控制台打印。
补上navigator['Netscape'] = {},报错r未定义,将r[e]改为扣下来的函数i,运行后报出 $_DAECn 未定义,直接搜索,找到定义的地方,直接扣下来再次运行
补上n后创建新的i函数(直接调用是无法实现加密),得到参数_。
4.2.3 逆向参数u
在u生成处断住,很明显u是将e、n传入一个函数r[a][$_DAEDN(919)][$_DAEDN(974)]后得到的数据
其中n为写死的字符串,在控制台打印e,发现是一些参数组成的字典:其他参数都可写死或从第一次返回的数据拿到,所以只需拿到userresponse和pow_sign的值就可以拿到e。
e = {
"setLeft":155, //setLeft为滑动距离
"passtime":561, //passtime为滑动滑块所用时间,可写死
"userresponse":156.0837155051295,
"device_id":"",
"lot_number":"4b01031db6db4e839f65d45049e0cf47", //lot_number、pow_msg为第一次请求返回的值
"pow_msg":"1|0|md5|2024-06-04T15:40:49.408771+08:00|24f56dc13c40dc4a02fd0318567caef5|4b01031db6db4e839f65d45049e0cf47||69a952b3088e6196",
"pow_sign":"97e56d1597be74eec312b449f3b49f0a",
"geetest":"captcha",
"lang":"zh",
"ep":"123",
"biht":"1426265548",
"4LaE":"gOku",
"em":
{"ph":0,"cp":0,"ek":"11","wd":1,"nt":0,"si":0,"sc":0}};
直接搜索pow_sign的unicode编码,打上断点断住后跟进函数,发现有个MD5的调用,猜测是将p传入MD5加密得到,测试后确实如此,那就直接调用本地的MD5库。
之后全局搜索userresponse的unicode编码,直接定位10处,打上断点,运行,发现断点停在表达式处,多运行几次,发现t[$_FFEIr(1480)]为定值,a为滑动距离,userresponse解决。
整合后e的代码如下:
userresponse = setLeft / 1.0059466666666665 + 2;
e = {
"setLeft":setLeft, //setLeft为滑动距离
"passtime":561, //passtime为滑动滑块所用时间,可写死
"userresponse":userresponse ,
"device_id":"",
"lot_number":lot_number, //lot_number、pow_msg为第一次请求返回的值
"pow_msg":"1|0|md5|"+ datetime + "|24f56dc13c40dc4a02fd0318567caef5|"+ lot_number +"||"+ n,
"pow_sign":CryptJS.MD5("1|0|md5|"+ datetime + "|24f56dc13c40dc4a02fd0318567caef5|"+ lot_number +"||"+ n).toString(),
"geetest":"captcha",
"lang":"zh",
"ep":"123",
"biht":"1426265548",
"4LaE":"gOku",
"em":
{"ph":0,"cp":0,"ek":"11","wd":1,"nt":0,"si":0,"sc":0}};
解决e,n后,就需要找到函数r[a][$_DAEDN(919)][$_DAEDN(974)],控制台打印后进入函数,发现和参数_类似,直接把大函数n和前面的定义函数后下来扣下来运行(注意,函数n得改成其他名称,n在之前定义为了字符串,我这里改成了n_),将e转换成字符串后得到结果。
4.2.4 逆向函数g[$_DAEDN(162)]
直接断点加控制台输出,跳转到函数位置,copy函数到本地,运行后得到结果
5 携带w请求url
将所得参数写入params,请求成功。
至此,极验4代滑块逆向完成。
完整代码:https://github.com/Ttanxuan/reverse/blob/main/%E6%9E%81%E9%AA%8C%E6%BB%91%E5%9D%974.js