JS逆向|某验三代一键通过模式(2023-3-6)
前言
该文章为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系作者删除~
需求
网址:9779f3db29102216253fa52d7e56074b
步骤
通过抓包其实分析到,完成整个验证需要四次请求:
1、请求demo/gt/register-fullpage,请求参数是一个时间戳,返回challenge和gt
2、请求get.php,请求参数是challenge和gt和第一次w,返回一个列表c和字符串s
3、请求ajax.php,这个接口是验证接口,请求参数是challenge和gt和第二次w,返回validate
4、请求gt/validate-fullpage,这个是提交接口,请求参数是validate和challenge,返回登录成功信息
因此,我们只要还原2次w的生成过程即可。目前js版本号为:fullpage.9.1.3.js
先看结果:
正文
第一次W值
JS是对于变量名做了Unicode混淆的,w对应的Unicode编码是\u0077。所以直接搜"\u0077"就能对位到生成位置。在7945行
i和r都能在上方找到
r值
r = t$_CFAAK(1392)
进入方法内部
实际上t就是r的值,还原一下,e参数实际上不用传
vart=newX()['encrypt'](this['$_CCGQ')]())// 拆分一下this['$_CCGQ')]()// 这里是生成16位的随机数,写死就可以了newX()['encrypt']()// 用导出的方法实现关于16位的随机数建议写死就好了,接下来有好几处需要用到,必须是一样的,否则会报错。
搜X = ,可以定位2046行,把代码全扣下来,导出方法如下
后面的一些加密算法基本上是用这种方式导出的
i值
o=$_BEZ()['encrypt1'](ge[$_CFAAK(330)](t[$_CFAAK(275)]),t[$_CFAAK(1381)]())i=m[$_CFAAK(1343)](o)i的生成需要o,所以先还原o
ge[$_CFAAK(330)](t[$_CFAAK(275)])// 是以下的一段字符串,这里只需要把上一个接口获取到的gt和challenge写进去就可以了,其它的没有进行校验。t[$_CFAAK(1381)]()// 是上文提到的随机数。i值的话就把m这个对象导出来,调用’$_EJv’这个方法就可以了
第一次w的值就出来了。w = i + r
第二次W值
第二次w的值加密位置是不一样的,可以通过跟栈去跟到。在8236行,i[$_CGCFE(1466)]就是w的值。
还原一下:
r='{'+i[$_CGDAc(1469)]+'"captcha_token":"'+'1080767038"}';// captcha_token我这里是写死的,不过js版本如果更新的话,估计这个也会变var_=$_BEZ();i[$_CGCFE(1466)]=m['$_EJv'](_['encrypt'](r,i[$_CGCFE(1381]()));// i[$_CGCFE(1381]() 是16位随机数// 这里需要把_这个对象导出, _ = $_BEZ(),实际上是把$_BEZ这个方法导出。i[$_CGDAc(1469)] 是一个很大的字典转为的字符串
这里面的某些参数我们需要写活的。它的生成位置在8174行,a参数。a是一个很大的列表。
这里其实我们只要看每个参数的值是如何生成的,然后模拟她生成
其中里面的tt、h、hh、hi、fp、lp、em、passtime、rp这些参数我是写活了。以下就是这些参数的写活方式:
tt
由一个方法生成,这个方法可以直接扣下来如下。传了3个参数,第一个参数与轨迹相关,这个可以写死的。第二第三参数是上一个接口返回的c和s
tt_=function(e,t,n){if(!t||!n)returne;varr,o=0,i=e,a=t[0],s=t[2],c=t[4];while(r=n['substr'](o,2)){o+=2;varu=parseInt(r,16),l=String['fromCharCode'](u),_=(a*u*u+s*u+c)%e['length'];i=i['substr'](0,_)+l+i['substr'](_);}returni;}('M*d8PjAA3(2N45((((BA((5:,GJTK))hMMJUG0GBK7HO5I.-IVkhRTG1/0i_,QM)d-BLq((,,80WY:ML1:MAb9q)*Y-1b9L))P9P(?/)(),*M9b9/*M)qqM)O((8bq8bn?ZHjM-U3)M93)(?*)(E-(M9-13)ME7)MP/)(U-(I(',c,s)h
h是由n参数经过了几个加密方法,这几个加密方法之前有导出过,大家测试一下就知道了。然后外层是一个md5加密而成的。n参数里面有一个时间戳需要写活一下。
hh
hh是把上面的n参数进行了md5加密
hi
hi是以下参数通过md5加密而成,也是有个时间戳,写活就可以了
fp、lp
这两个参数也是把时间戳写活
em
这个的话实际上是window.profermance.timing
貌似写死也可以,简单模拟一下
tm_={"a":newDate().getTime(),"b":newDate().getTime(),"c":newDate().getTime(),"d":0,"e":0,"f":newDate().getTime(),"g":newDate().getTime(),"h":newDate().getTime(),"i":newDate().getTime(),"j":newDate().getTime(),"k":newDate().getTime(),"l":newDate().getTime(),"m":newDate().getTime(),"n":newDate().getTime(),"o":newDate().getTime(),"p":newDate().getTime(),"q":newDate().getTime(),"r":newDate().getTime(),"s":newDate().getTime(),"t":newDate().getTime(),"u":newDate().getTime()}passtime
这里我是把lp和fp两个时间戳相减得出。不过js里貌似不是这样做的。反正这样也能过就没管了
rp
rp是gt+challenge+passtime的值然后通过md5加密
————————————————————————
到此,第二次w的值就可以通过以上所说去生成出来了。接下来的流程就很简单了~~~~~
最后
欢迎联系作者交流更多