请求流程分析
首先是一个get请求,参数里有bsskey和bss,返回一个base64编码的字符串imgId
随后会把这个imgId作为参数去请求图片data:image/jpeg;base64,iVBORw0KGgoAAAAN...
滑动滑块的过程数据包如下,带有bsskey参数和vi参数
vi就是轨迹验证参数,一般是x,y,date,等等组合的数据,后端会校验vi是否是正常轨迹,如果通过则会返回checksign
后续会带上checksign去登录
图片请求
请求的base64解码之后的图片直接就是完整图片,不需要还原
现在就是去分析bsskey参数,通过函数栈在e.registerWithLogger下断点
断下来之后直接看函数栈就行,或者跟一下也行,可以发现在_initCaptchaComp函数中,bsskey是一个被固定的值
1 | import requests |
轨迹vi参数生成
在validate请求上的函数栈打下断点,断在t.exports函数处
断下来之后再去看函数栈,跟到e.validateWithLogger的时候发现参数还是加密的,说明加密的函数还在前面
往上找到匿名函数,可以发现这里参数是没加密的,可能加密逻辑就在这里,在匿名函数处下断点
1 | w.on("validate", (function(t) { |
通过查看变量可以发现,此时t变量是明文,n是加密之后的参数,所以加密逻辑在这里
先解释一下t里面的各个参数的含义
downY是鼠标按下的时候,鼠标距离浏览器上端的距离,upY是鼠标抬起的时候,鼠标距离浏览器下端的距离,这两个参数一般不用在意,固定一个值就行
left是滑块滑动了多少距离,这个和滑块缺口有关
track值如下
track怎么生成的呢?既然这里有w.on("validate", (function(t)监听事件,那么肯定在前面有触发这个信号的
继续往上追函数栈可以发现,e.emit函数触发了validate信号
先看段代码,包含了几个参数
1 | e.emit("validate", { |
这里的left参数的值是m()函数返回的,m()函数就是返回滑块滑动的距离,这里不再赘述
c的生成逻辑如下
1 | n._bindEvent = function(t) { |
这里clientX是距离浏览器左侧的距离,clientY是距离浏览器上侧的距离,clientY一般可以只变一两个像素
0,0的序列实际上不用管,可以写成固定的,至于原因,我也没分析出来,从1,1开始到最后的2,1结束,才是真正滑块移动的轨迹,而且最后一个2,1序列的clientX减去第一个1,1序列的clientX的值,就是参数left的值
最后分析一下加密函数,也就是这里的o.default和u.encrypt
1 | w.on("validate", (function(t) { |
单步跟一下会发现o.default其实啥也没做,主要是u.encrypt
1 | e.encrypt = function(t) { |
这里i.default其实就是return r.JSON.stringify.apply(null, arguments) ,也就是把参数给转字符串了,加密函数在o.btoa
1 | e.btoa = function(t) { |
先扣这么一段代码
1 | function encParam(t) { |
参数是在打断点的时候直接得到的
运行的时候报错ReferenceError: o is not defined,o是固定值ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
剩下就是分析这里的几个参数是怎么来的了
1 | vi: (0,o.btoa)((0,i.default)({ |
s是固定值,l是向右滑动的距离,dy是鼠标按下的时候距离上端的距离,uy是鼠标松开的时候距离上端的距离,t的话就是伪造就行了
代码
1 | import requests |
轨迹伪造
0,0的序列可以不用管,固定就行,从1,1开始的x坐标,到2,1或者3,1结束的x坐标,两者之差要等于滑动的距离,y的坐标可以不变,x轴的递增可以随机递增,
1 | import random |
















