逆向爬虫30 某验四代滑块验证码
本文参考了CSDN另两位博主,分别是 SerendipitySpider 和 带泪的鱼,因为他们已经把大体流程都完成了,这里总结了下自己扣代码的经验
一. 抓包分析请求过程
二. 定位加密参数改写JS
challenge:参考值,4ed83c16-da5d-46a8-890a-d138518a0a71
全局搜索
callback:参考值,geetest_1650294566413,很简单,geetest_ + 时间戳
w:轨迹加密值,全局搜索搜不到,因为变量名都通过 unicode 加密隐藏起来了,可以看调用栈跟值定位,也可以直接搜索 "\u0077"
来找w的生成位置
// w等于r
r = d[$_BHHFU(91)](l[$_BHHFU(91)][$_BHHGm(541)](e), a)
// 等价于
r = d['default'](l['default']['stringify'](e), a)
/*
先看参数:
e是个对象,包含以下键值,和轨迹相关
device_id、ep、f3st、geetest、lang、lot_number、passtime、pow_msg、pow_sign、setLeft、track、userresponse
a是this,里面参数看不懂,先不管,等跟进函数后看了再说,不一定用得到
l['default']['stringify']的效果等价于JSON.stringify
再看函数:
d['default']是生成r的加密函数,因为参数无法立即确定,所以不能直接扣这个d['default'],跟进去看看
*/
// d['default']函数返回
return c[$_CEAAg(139)](o) + a;
// 等价于
return c['arrayToHex'](o) + a;
// 先看参数a和o
// 找a
a = new _[($_CEAAg(91))]()[$_CEABJ(757)](n);
// 等价于
a = new _['default']()['encrypt'](n);
// 先看参数n
var n = c[$_CEAAg(181)]()
// 等价于
var n = c['guid']()
/*
没有参数,直接分析:
c是个对象,直接导出对象c,调用['guid']即可
*/
/*
回到 a = new _['default']()['encrypt'](n); n已经确定,分析前面
_是个对象,直接导出对象_,按照这里的方式new,再调用['encrypt'],生成a
*/
/*
回到 return c['arrayToHex'](o) + a; a已经确定,找o
*/
var o = i[$_CEAAg(91)][$_CEAAg(757)](e, n);
// 等价于
var o = i['default']['encrypt'](e, n);
/*
n已经确定,e是函数传进来的第一个参数,轨迹相关
i是个对象,直接导出对象i,按照这里的方式调用['default']['encrypt'],生成o
*/
/*
回到 return c['arrayToHex'](o) + a; a和o都已经确定
前面生成n的时候,对象c已经导出,按照这里的方式调用['arrayToHex'],返回r值(w值)
*/
/*
小结:
这里所有的方法均导出,只有函数的参数e(轨迹相关)没有确定,封装好函数,传入e,返回r值(w值)
*/
对象e的值:
/*
文件unicode解码后,可以很容易地在文件中搜索到生成这些值的地方,除了轨迹需要自己生成
动态变化的值有:
lot_number: 前面返回的
passtime: 滑块滑动事件
pow_msg: "1|0|md5|{datetime}|{captcha_id}|{lot_number}||{uuid}"
pow_sign: md5(pow_msg)
setLeft: 滑块轨迹缺口识别距离,即滑块需要移动的距离
track: 轨迹
userresponse: set_left/1.0059466666666665 (1.0059466666666665这个值可能会变)
*/
轨迹生成参考带泪的鱼
三. 扣代码小结
- 扣代码时,看到对象优先导出对象,如果用到了这个对象下面多个方法,只需导出对象一次即可。
- 定位到加密方法后,如果参数不好确定,可以先进函数看下,参数是否决定加密结果,我第一次看的时候,就被卡死在方法入口的 参数a 上面了,结果 参数a 并不会参与加密计算。