当前位置: 首页 > Web前端 > JavaScript

【验证码逆向专栏】一个二代滑块验证码逆向解析

时间:2023-03-27 14:05:05 JavaScript

声明本文所有内容仅供学习交流,抓包内容、敏感网址、数据接口等内容均已脱敏处理,并严禁用于商业用途和非法使用,否则由此产生的一切后果与作者无关,如有侵权,请立即联系我删除!本文未经许可禁止转载,修改后禁止二次传播。对于因未经授权使用本文所解释的技术而导致的任何事故,作者概不负责。如有侵权,请第一时间联系作者公众号【K爬虫哥】删除!逆向目标target:一个二代滑块验证码主页的逆向分析:aHR0cDovL3d3dy5qc2dzai5nb3YuY246NTg4ODgvbWluaS9uZXR3ZWIvU01MaWJyYXJ5LmpzcA==说明:大部分逻辑其实和三四代一样,一样缩写。有疑惑可以看之前的文章【验证码逆向专栏】某测试三代滑条的验证码逆向分析【验证码逆向专栏】四代滑条的验证码逆向分析的一个测试。返回挑战和GT。有一个get.php请求,返回一个新的挑战。这个请求之后的操作必须使用这个新的challenge,否则验证不成功。其他还有验证码背景图片,乱序图片地址,c和s的值是等价的,之前写的三代文章都差不多,这里就不一一分析了。然后是ajax.php是否验证通过,通过后返回一个validate。请求还需要我们的反向w参数:那么也是netWebServlet.json接口,get.php请求返回challenge,ajax.php返回validate,请求获取name字段。后续搜索数据,带上这个名字即可:做过三四代逆向分析的都知道,我们可以直接搜索w的Unicode值\u0077来定位,但是二代不是Unicode,而是十六进制编码,搜索\x77定位。当然,按照正常的流程,顺着栈就可以轻松找到加密的位置。获取H7z值从上图我们可以知道w的值为r7z+H7z,先看H7z。按照这个方法,我们来到了一大系列的控制流程。这里推荐使用AST来恢复。后续可能会有一些循环。RSA加密随机字符串,有三代和四代之分,这里不再赘述。得到r7z值然后r7z,主要由以下两段代码生成:q7z=n0B[M9r.R8z(699)](h7B[M9r.C8z(105)](Y7z),V7z[M9r.R8z(818))]())r7z=p7B[M9r.R8z(260)](q7z)可以看到有一个变量Y7z参与了计算。首先,让我们看看它是怎么来的。您可以通过直接搜索找到它。可以发现同样是16-in系统的编码,由五个值组成:userresponse,passtime,imgload,aa,ep。获取用户响应值,并一一分析。首先是用户响应。将滑动距离和挑战值传入一个方法得到一个9位数的字符串:中间的g7z就是滑动距离。您可以通过搜索查看定义的位置。用尺子测量并比较。与滑动距离一致:那么我们来看看方法。跟着它还有一大串switch-case的控制流程:还原代码如下:functiongetUserResponse(L0z,o0z){for(varj0z=o0z.slice(32),c0z=[],X0z=0;X0z57?K0z-87:K0z-48;}j0z=36*c0z[0]+c0z[1];vark0z=Math.round(L0z)+j0z;o0z=o0z.slice(0,32);varn0z,f0z=[[],[],[],[],[]],Q0z={},N0z=0;X0z=0;对于(vari0z=o0z.length;i0z>X0z;X0z++){n0z=o0z.charAt(X0z),Q0z[n0z]||(Q0z[n0z]=1,f0z[N0z].push(n0z),N0z++,N0z=5==N0z?0:N0z);}变量y0z,v0z=k0z,B0z=4,x0z="",I0z=[1,2,5,10,50];while(v0z>0){v0z-I0z[B0z]>=0?(y0z=parseInt(Math.random()*f0z[B0z].length,10),x0z+=f0z[B0z][y0z],v0z-=I0z[B0z]):(f0z.splice(B0z,1),I0z.splice(B0z,1),B0z-=1);}returnx0z;}获取passtime值passtime不需要考虑如何通过函数获取。生成相同,获取语句为:varpasstime=track[track.length-1][2],如下图,track的最后取值时间为871,passtime的取值也是871获取imgload值imgload也没什么特别的,从字面意思猜测应该是加载图片需要时间,实测可以直接写死,或者整个随机值就够了。获取aa的值aa的值为F7z,如下图:搜索F7z,定位到下图所示的地方,将一个时间戳传入一个方法:后续也是一个switch-case的控制流程,需要注意下图中c7B[M9r.R8z(781)](M9r.R8z(764),K1z)的值其实就是轨迹。这个函数getF7z(track){varo5r=6;对于(varN1z,X1z=s6z(track),f1z=[],B1z=[],o1z=[],t1z=0,j1z=X1z.length;t1z=17705?o5r/3:o5r*3;}}返回f1z.join("")+"!!"+B1z.join("")+"!!"+o1z.join("");}functions6z(F6z){for(varY6z,g6z,a6z,E6z=[],D6z=0,P6z=[],J6z=0,l6z=F6z.length-1;J6z=m6z&&(W6z=m6z-1),W6z&&(Z6z=d6z.charAt(W6z)),H6z%=m6z;varq6z="";返回r6z<0&&(q6z+="!"),Z6z&&(q6z+="$"),q6z+Z6z+d6z.charAt(H6z);}函数u6z(R6z){for(varz6z=[[1,0],[2,0],[1,-1],[1,1],[0,1],[0,-1],[3,0],[2,-1],[2,1]],h6z=0,C6z=z6z.length;h6z=t["长度"]?“。”:t["charAt"](e);}function$_HBO(e,t){returne>>t&1;}function$_HCX(e,o){vari=this;o||(o=i);for(vart=function(e,t){for(varn=0,r=24-1;0<=r;r-=1)1===$_HBO(t,r)&&(n=(n<<1)+$_HBO(e,r));返回n;},n="",r="",s=e.length,a=0;a