【JS逆向练习】极验三代滑块模式验证码逆向分析(上)
作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
前言#
上一篇,分析了一键通过模式的验证,这次准备把对滑块验证分析的过程更详细记录下来
地址:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s
流程分析#
首先进入 验证码 __ 地址,然后点击弹出滑块,完成并通过验证。整个过程抓包,发现共涉及了5个请求。
1、register-slide
主要返回了gt和challenge,下一个接口get.php的主要参数。
2、get.php
关键入参有:gt、challenge、w(第一个w,记为w1),返回c和s后续会用到。
3、ajax.php
点击按键验证,会弹出滑块窗口,然后调用ajax.php。 入参同样带了gt、challenge、w(第二个w,记为w2),接口返回验证码的 类 __ 型,返回的结果虽然没用到,但是如果不请求或者请求不带 w 后面都会报错。 第二个w如果如果生成的结果不对,也会影响最后一步ajax.php的验证,比如返回forbidden。
4、get.php
这里又会有一个get.php,仍然返回c和s以及滑块图片和底图,34位的challenge。
5、ajax.php
最后,滑动完成拼图,得到验证结果 validate 参数,这个参数就是后续登录的令牌,在后续操作的请求中会用到。 入参涉及第三个w、challenge(第二次调用get.php返回)、gt。
逆向分析#
w1#
由上分析知道,第一个w参数在第一次调用get.php时候涉及了,所以首先找到第一个w的生成入口。这里直接搜"\u0077"
"w"=i+r,先分析第一个r值来源,在6970行var r = t[$_CEEJl(1169)]()
接下来进入这个t[$_CEEJl(1169)]函数,看下在哪生成的值。
这里生成t并返回的 var t = new X()$_CGCJs(17)](e));
这里是个md5加密,参数是16位随机字符串,自己随便生成就行。不过后续还会用到。要保持一致都用这个16位随机字符串。
加密方法可以扣代码,或者自己引库复现。我这里是赋值到全局变量 window下 了,省点事。代码参考
r复现完成后,还剩个i,接下来继续看怎么生成的。
发现
i = p[$_CEEJl(1151)](o),然后里面传个o参数
o = $_BF_()[$_CEEIh(1184)](he[$_CEEIh(491)](t[$_CEEJl(363)]), t[$_CEEIh(1119)]())
所以需要先看下o怎么生成的。
o = $_BF_()[“encrypt1”](he["stringify"](t[$_CEEJl(363)]), t[$_CEEIh(1119)]()),先简单还原的混淆的变量方便观察。
发现也是个加密,然后把第一个参数
t[$_CEEJl(363)]转义成json格式,第二个参数t[$_CEEIh(1119)]()其实就是刚才的16位随机字符串。我们把t[$_CEEJl(363)]内容贴出来,看下都有哪些内容。
这里只有gt、challenge是动态的,其它固定即可。
这样分析下来入参明确的,把o的加密代码扣下来或复现即可,我这边还是扣代码。参考代码
至此第一个w还原完成。
w2#
第二个w,是第一次调用ajax.php涉及到了。这里只能跟栈,不能搜"\u0077"找到入口了。 跟栈过程跳过了,具体可以看上一篇一键通过验证的分析,在$_CDIo这里。
w是n对象下的一个属性,是通过t的"$_CEAw"属性赋值的。需要分析下在什么时候"$_CEAw"赋值了
可以看到在t[$_CFCIL(1160)]()时候,还没有"$_CEAw",执行后有了,所以重点在t[$_CFCIL(1160)]()
进到t[$_CFCIL(1160)]()函数内部找下相关生成位置,在7233行,发现有赋值的地方
i[$_CFFII(1147)] = p[$_CFFII(1151)](c[$_CFFII(17)](r, i[$_CFFJL(1119)]()));分析下这行代码i[$_CFFII(1147)] = p["$_HEz"](c["encrypt"](r, i[$_CFFJL(1119)]()));还原下部分混淆名称发现也是个加密,参数是r和i[$_CFFJL(1119)](),r是个对象,i[$_CFFJL(1119)]是16位字符串,还是w1时候的那个。接下来看下r的生成位置,这里很明显就在上两行。
r = $_CFGDr(793) + i[$_CFGEA(1183)] + $_CFGEA(1145) + n(o[$_CFGEA(22)]() + n(n[$_CFGEA(22)]()) + n(e[$_CFGEA(22)]())) + $_CFGEA(1193);
下个断点,看下是哪些内容。
发现也是一些参数,贴出来看下。
这里rp是动态的,passtime固定,但后面涉及的时候要保持一致。重点rp看下怎么还原。发现是在i[$_CFGEA(1183)]里包含的。
继续看i[$_CFGEA(1183)]在哪赋值的,i[$_CFGEA(1183)]还原混淆名字是i["$_CEC_"],在7187这行里rp生成并且赋值"$_CEC_"里,这里其实比较绕,可以手动还原一些代码,更容易理解和找到。
rp=MD5(gt+challenge+passtime),passtime和上述的一样。把拼接内容md5加密就可以了,我这边引库。
参考代码
至此rp拿到,r还原完成,回到w生成入口。发现还需要把r加密下,i[$_CFFJL(1119)]()是16位字符串(和前面一样)也是RSA加密的密钥,向量是0000000000000000。
加密代码如果引库的话,向量可以自己跟进去加密函数内,拿到iv字节 数组 __ 还原下。
贴下工具代码
我这边依旧是扣代码,和w1的加密一样就是调用的加密方法不一样,w1调用的encrypt1,w2是encrypt。贴下参考代码
至此第二个w分析完成。
w3#
第三个w是在slide这个js里,可以跟栈或搜"\u0077"找到。
w=h+u,先分析u的还原,是个r函数,进入内部,发现var e = new U()[$_CBFJN(392)](this[$_CBGAK(744)](t));这里生成。
参数还是16为字符串,用之前的就可以。
加密代码,还是扣一下,把U这个函数扣下来,缺什么环境再补下。
u完成之后,还剩一个h需要还原。发现h是由m函数生成,入参是l,l是个加密参数是o r[$_CAIAK(744)]()是16位字符串,和之前一样即可。
先看下o的内容,这里passtime,aa,ep,rp,userresponse都是动态的需要还原,其余固定。 注:首先passtime是滑动轨迹里的滑动时间,一定要和最后轨迹数组的最后一个元素的z相同
接下来先看rp的还原,就在u的上方,很容易观察到。o=gt+challenge(32位的)+passtime challenge在第二次调用get.php返回的是34位的,在32位的后面多了2位,前32位一样
rp完成后,继续看ep。往上翻,就能找到o的生成。
ep是个r函数生成的,进入函数内部看下。返回一个对象
v:版本号 $_BIE:布尔类型,固定false me:布尔类型,固定true tm:动态生成 td:固定-1 所以继续分析tm,new了一个bt,先把bt扣一下。
里面 $_BGGX属性也需要扣下
贴下代码
结果验证没问题,ep完事继续userresponse还原。
ep是H函数生成,参数t是滑动距离,i[$_CAHJS(134)]是34位challenge。扣下H函数即可
试下结果没问题,继续最后一个aa
aa是由e赋值的,e是当前函数的入参,需要看上一个栈找下
发现是l生成的















































