JS逆向|某验三代一键通过模式(2023-3-6)

文章详细解析了一个使用JavaScript实现的复杂验证码验证过程,包括四个关键请求步骤和两次W值的生成。文中提供了W值生成的详细代码还原,涉及到随机数、加密函数以及特定参数的构造,如tt、hh、hi等。文章强调了模拟这些生成过程对于理解和破解验证码系统的重要性。
摘要由CSDN通过智能技术生成

前言

该文章为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系作者删除~

需求

网址: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参数实际上不用传

var t = new X()['encrypt'](this['$_CCGQ')]())
// 拆分一下
this['$_CCGQ')]() // 这里是生成16位的随机数,写死就可以了
new X()['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)
        return e;
    var r, o = 0, i = e, a = t[0], s = t[2], c = t[4];
    while (r = n['substr'](o, 2)) {
        o += 2;
        var u = parseInt(r, 16)
            , l = String['fromCharCode'](u)
            , _ = (a * u * u + s * u + c) % e['length'];
        i = i['substr'](0, _) + l + i['substr'](_);
    }
    return i;
}('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": new Date().getTime(),
    "b": new Date().getTime(),
    "c": new Date().getTime(),
    "d": 0,
    "e": 0,
    "f": new Date().getTime(),
    "g": new Date().getTime(),
    "h": new Date().getTime(),
    "i": new Date().getTime(),
    "j": new Date().getTime(),
    "k": new Date().getTime(),
    "l": new Date().getTime(),
    "m": new Date().getTime(),
    "n": new Date().getTime(),
    "o": new Date().getTime(),
    "p": new Date().getTime(),
    "q": new Date().getTime(),
    "r": new Date().getTime(),
    "s": new Date().getTime(),
    "t": new Date().getTime(),
    "u": new Date().getTime()
}

passtime
这里我是把lp和fp两个时间戳相减得出。不过js里貌似不是这样做的。反正这样也能过就没管了

rp
rp是gt+challenge+passtime的值然后通过md5加密

————————————————————————

到此,第二次w的值就可以通过以上所说去生成出来了。接下来的流程就很简单了~~~~~

最后

欢迎联系作者交流更多

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值