极验滑块验证三个W超详细解密(3)
书接上文
5.第五个请求,返回生成验证码的三张图片
1 |
|
图片处理
乱序处理
图片下载下来后,发现是乱序的,在页面里面发现canvas, 怀疑可能是对图片进行了重绘
我们直接在 事件侦听器断点中,监控一下画布,
刷新一下验证码,断点进来,我们看一下代码,可以看到 i和e都是canvas,却别在于一个显示,一个不显示,o和s是两个画笔,i中写入乱序的背景图,而s画笔会在此基础上对乱序的图片进行重绘
我们直接看他是怎么重绘的
c的值是x轴的坐标,图片分成52份,上面26份,下面26份,
u 的值 是判断数组中的值是否大于25,否则返回80或者0 ,这里代表的是画布的高度是160,然后分成上下两部分,上面26份,下面26份,80和0都是y轴的坐标
l的值,是从画布o,就是乱序的图里面 c ,u xy轴坐标,10指图片的宽度,a,指图片的高度
s[$_CJEq(95)](l, _ % 26 * 10, 25 < _ ? a : 0);
这里代表的意思是 s[“putImageData”] 就是从乱序的图片里面获取l,然后再通过顺序写入到新的图片里面去, Ut就是图片还原的正确顺序
我们直接用python 还原就好了
1 |
|
滑动距离
使用opencv进行处理
1 |
|
滑动轨迹
使用随机算法生成
1 |
|
6.第六个请求,验证验证码是否成功
滑动滑块,生成最后一个请求,该请求同样需要携带w,唯一的区别在于这个w相比较之前的w更短一点,而且challenge参数会和之前不一样,多了个cb,这个参数是来自于第五个请求返回的新的challenge,需要注意
第三个W解密流程:
从发起程序中进入堆栈,同样按照最开始的流程 搜索”\u0077”,只有一个,直接断点进来,其中h + u就是我们要的w
我们把这里一大段代码都扣下来,看一下具体代码流程, 传入的参数通过调试可知分别为滑动的距离、被加密后的轨迹、滑动的时间,o当中的参数的最后一个, 他其实跟之前写的那个鼠标移动的轨迹时间是一样的,我们也同样可以用之前算差值的方法算tm的参数
1 |
|
1 |
|
H方法是一个控制流,和之前的一样,它的控制判断流程没有意义,直接拿循环的主题部分就好了
1 |
|
然后我们再处理一下轨迹,即找一下e的加密过程,看一下这边轨迹做了哪些处理,我们把堆栈往上走一步,这个l呢就是轨迹处理,第一个参数就是轨迹, l = n[$_DAAAt(912)][$_CJJJp(1034)](n[$_DAAAt(912)][$_CJJJp(1069)](), n[$_DAAAt(71)][$_DAAAt(1091)], n[$_CJJJp(71)][$_DAAAt(389)])
这段代码有点长,我们先看,我们处理一下
外层的括号代表是一个方法 n[$_DAAAt(912)][$_CJJJp(1034)]
,该方法传入三个参数,第一个参数是 n[$_DAAAt(912)][$_CJJJp(1069)]()
,可以很明显的看到,[$_CJJJp(1069)]
是 n[$_DAAAt(912)]
原型链上的一个方法,其实就相当于 `[$_CJJJp(1069)].n[$_DAAAt(912)] 我们把外层的方法和里面的方法一起抠出来
1 |
|
抠出来整理后的代码是这样的
1 |
|
需要注意的几个地方,一个是这里,括号里面的那个方法没有传递参数,但实际上这个就相当于参数传递,这个东西是轨迹,this.轨迹,这就是为什么是原型链上的方法,因为this的作用域指向的就是轨迹,所以这里我们直接从函数上面把轨迹传递进来就好了
还有一个地方是这里, 这里新建了一个ct方法,然后再ct方法的原型链上又添加了一个新方法,我们需要把这两个方法找出来
1 |
|
接下来我们就可以测试一下括号内的方法有没有什么问题了,运行结果没什么问题,那我们就看下一个外层的方法
我们先看下外层方法的另外两个参数 n[$_DAAAt(71)][$_DAAAt(1091)], n[$_CJJJp(71)][$_DAAAt(389)]
简化一下就是 n[$_DAAAt(71)]["c"], n[$_CJJJp(71)]["s"]
而c 和 s就是上一个请求,即获取验证码图片的那个请求中的c和s参数,我们这里先固定写死,后面再传参
运行一下,和浏览器里面一样,这样l参数我们就解决了,也就是被加密的轨迹 e参数解决了
现在 我们回到最开始的try 条件那里,看一下这一部走了什么,我们的最终目的是为了完成 h + u,在这里还需要知道o是什么,而o是在try之前就做了定义,这一段try catch会非常头疼,所以我们直接看结果,看一下进try之后做了什么
将断点设在上下两个地方,可以很明显看到就多了一个 h9s9的值,而其它值我们已经搞定了,而这个值好像又和random值有关系,那么我们也可以直接在这里用定值,直接把try catch这一段给删掉,然后给o加定值,而且这个值并没有在后续进行校验,所以可以随便给,再整理一下,就是这样了
1 |
|
然后我们再看一下X方法,X方法比较长,它其实是一个md5方法,随便抠一下就好了,运行结果和md5方法一样就可以了
1 |
|
在接下来就剩下最后的 u l h 的计算了 , u = r['$_CCDf']()
u其实是RSA加密,跟第一个W那里的RSA加密一模一样,把相关的函数和参数挪过来就好了, $_CCIl
就是aeskey
1 |
|
接下来就是l参数了 l = V['encrypt'](JSON['stringify'](o), r['$_CCEV']())
这里就是个aes加密,和第一个w里面扣的时候一模一样
1 |
|
然后 h = m['$_FEE'](l)
这里和第一个w那里的 i = $_HEf(o)
处理方式一模一样,同样呢直接挪过来
1 |
|
最终将代码整理一下,看一下跑出来的结果,看上去好像没什么问题,然后我们回去处理一下轨迹和滑动距离
1 |
|
提交验证
最后也是没有任何问题,验证成功
1 |
|