数美滑块的js逆向分析

本文详细介绍了数美滑块验证码的验证步骤和过程解析,包括register请求获取图片信息、fverify请求进行验证,以及动态参数ml、ee、ra的加密方式。此外,还探讨了conf请求中获取的js版本信息对自动化的影响,以及文字点选、图标点选、语序点选和空间推理等扩展验证内容。

一、引言

1.1 声明

声明:
  本文章仅供学习交流使用,不提供完整代码,严禁用于商业用途和非法用途,否则由此产生的一切后果均与本人无关,请各位自觉遵守相关法律法规。
  本文章未经许可禁止转载,禁止任何二次修改(加工)后的传播;若有侵权,联系删除。

交流、合作请留言,24小时内回复!

1.2 简介

测试用例地址:aHR0cHM6Ly93d3cuaXNodW1laS5jb20vbmV3L3Byb2R1Y3QvdHcvY29kZQ==
在这里插入图片描述

放一张验证通过的截图,然后开始进入逆向。
在这里插入图片描述

1.3 待办

js代码会更新,但是频率不高,因此还未将js解析实现自动化,目前只是手动还原了一版。

二、验证步骤

通过在浏览器中的操作,可以看出 验证码的生成、验证分为两个步骤。
register请求 获取验证码图片信息 ----> 移动缺口图片到正确位置 发起fverify请求 进行结果验证。

2.1 register请求,获取图片地址

在这里插入图片描述

========================载荷参数解释========================
(绝大多数参数都可固定)
"channel": "DEFAULT",
"model": "slide",
"organization": "d6tpAY1oV0Kv5jRSgxQr",
"captchaUuid": "20230811181758TpK3YwejeykFnbZcF6",	// 日期时间 + 字符串(未研究)
"lang": "zh-cn",
"appId": "default",
"sdkver": "1.1.3",
"callback": "sm_1691749124176",	// sm_ + 时间戳
"rversion": "1.0.4",
"data": "{}"
========================响应数据解释========================
"code":1100
"message":"success"
"requestId":"24e34f217f0a496b49623449ddcbba52"
"riskLevel":"PASS",
"score": 0
"detail":{
	// 此处返回的信息在验证时需要使用
	bg: "/crb/set-000006/v2/106b23d54fc7789a4ab53f1b5f632694_bg.jpg",	// 背景图
	fg: "/crb/set-000006/v2/106b23d54fc7789a4ab53f1b5f632694_fg.png",	// 缺口图
	k: "0QeT1t/wBSI=",
	l: 8,
	rid: "20230811181847df3fc1677a95a41138",
}

2.2 fverify请求,滑块验证

验证成功返回 {riskLevel:“PASS”},验证失败返回 {riskLevel:“REJECT”}。
数美滑块在验证时提交的参数居然多达20个😟
在这里插入图片描述

三、过程解析

数美的滑块 相对来说不难,直接查看fverify的启动器,可以从上到下点击,进入js页面。
😆直接点第一个就行了
在这里插入图片描述

3.1 参数定位

进入到js源代码页面后,尝试搜索请求参数中的字段,看是否有结果。本次搜索以"hd"为例,共有28个匹配结果。可以一个个查看,确认是否为请求参数中的"hd",由图可知,本页面中的第22个"hd"附近还存在 与其他请求参数相同的字段信息。

在此下断点,滑动滑块,可以成功断住,记录此处生成的值,与fverify验证请求中的参数值对比可知,两者一致,此处正是 需要逆向分析的地方😎。
在这里插入图片描述

关键的东西就在此处了,可以慢慢地、一步步的调试,执行到此处可以发现请求参数 分散在两个变量中的,所以接下来需要分析这两个变量的生成过程。
在这里插入图片描述

多滑动几次滑块,可以发现,有些参数的值是固定的,在此也可以先跳过分析这些固定的参数。
在这里插入图片描述

3.2 动态参数

最终可知,变化的参数为 ml、ee、ra,通过跟踪代码可以发现三个参数的加密方向点如下:

  • ml 移动距离x加密
  • ee 移动轨迹数组加密
  • ra 时间戳差值加密

参数都为,des加密,每个参数对应一个密钥

在这里插入图片描述

3.3 图片缩放

请求到的图片尺寸为600✖300,前端渲染的图片尺寸为300✖150,识别缺口距离的时候需要修正。
在这里插入图片描述

四、扩展内容

4.1 conf请求,获取js版本信息

数美的js版本过段时间会更新,导致请求参数的名称和值也会改变,如果想要实现自动化,就需要考虑到更全面的问题。
验证参数中有两个参数 rversion 、protocol 是和js版本有关的,因此这里首先分析js的版本如何确定的问题。
通过在浏览器中抓包可以发现,有个conf请求,返回的是js版本的信息。
在这里插入图片描述
这个请求具有如下参数,需要还原的是captchaUuid(也可以固定)

"channel": "DEFAULT",	// 固定
"appId": "default",		// 固定
"sdkver": "1.1.3",		// sdk版本,captcha-sdk.min.js中固定的
"captchaUuid": "20230812091027KWJN8kH2nAdPGrGTpQ",	// 待分析(其实也可以固定)
"callback": "sm_1691802630571",	// sm_ + 时间戳
"rversion": "1.0.4",	// captcha-sdk.min.js的大版本号
"model": "slide",		// 验证模式,slide代表滑块
"lang": "zh-cn",		// 语言(简体中文)
"organization": "d6tpAY1oV0Kv5jRSgxQr"	// 企业标识(可以固定)

查看conf的启动器,点击进去第一个cmsp.min.js,搜索 captchaUuid,共有9个结果。
其中有个方法叫做 getCaptchaUuid,在此打上断点(其他可能的地方,也一并打上断点)。
刷新网页、选择滑块,会发现成功的在此断住,在return处打断点,直接运行到return处。
得到一串字符串,抓包对比,可知此处的getCaptchaUuid就是需要的captchaUuid参数生成的地方。
在这里插入图片描述

在这里插入图片描述
扣出 getCaptchaUuid方法,js做了混淆,结合浏览器进行调试。可以得到简化后的版本:

'generateTimeFormat': function _0x377dfb() {
    var _0x43e7ea = _0x59b24f
      , _0xf7a45e = new Date()
      , _0x2257b4 = function _0x51d189(_0x2bb897) {
        var _0x2b86fd = _0x22ab;
        return _0xc00995[_0x2b86fd(0x1b6)](+_0x2bb897, 0x2f * -0x22 + -0xdf6 * 0x2 + 0x111a * 0x2) ? _0xc00995[_0x2b86fd(0x65a)]('0', _0x2bb897) : _0x2bb897['toString']();
    };
    return _0xc00995['ZmJjz'](_0xc00995[_0x43e7ea(0x1c6)](_0xc00995['aqwMQ'](_0xf7a45e[_0x43e7ea(0x612)]()[_0x43e7ea(0x1a0)](), _0xc00995[_0x43e7ea(0x65e)](_0x2257b4, _0xc00995[_0x43e7ea(0x1c6)](_0xf7a45e['getMonth'](), -0xfaa + 0x17ac + 0x1 * -0x801))) + _0xc00995[_0x43e7ea(0x65e)](_0x2257b4, _0xf7a45e[_0x43e7ea(0x39a)]()), _0xc00995['nIfRW'](_0x2257b4, _0xf7a45e[_0x43e7ea(0x6d7)]())), _0x2257b4(_0xf7a45e[_0x43e7ea(0x3a9)]())) + _0xc00995[_0x43e7ea(0x65e)](_0x2257b4, _0xf7a45e[_0x43e7ea(0x39f)]());
},
'getCaptchaUuid': function _0x1b55e2() {
    var _0x1aa18f = _0x59b24f
      , _0x2468bc = _0xc00995[_0x1aa18f(0x150)][_0x1aa18f(0x2b6)]('|')
      , _0x22d1a6 = -0x2237 + -0xa * 0x6f + 0x8b * 0x47;
    while (!![]) {
        switch (_0x2468bc[_0x22d1a6++]) {
        case '0':
            var _0x3c1b53 = _0x5b1e90[_0x1aa18f(0x213)];
            continue;
        case '1':
            for (var _0x41ee97 = -0x85b * 0x3 + -0x1d6e + 0x367f; _0xc00995[_0x1aa18f(0x1b6)](_0x41ee97, -0xdce + -0x232 * -0x11 + -0x1772 * 0x1); _0x41ee97++) {
                _0x1c9d91 += _0x5b1e90[_0x1aa18f(0x11d)](Math[_0x1aa18f(0x624)](_0xc00995[_0x1aa18f(0x6af)](Math[_0x1aa18f(0x204)](), _0x3c1b53)));
            }
            continue;
        case '2':
            var _0x5b1e90 = _0x1aa18f(0x695);
            continue;
        case '3':
            return _0xc00995[_0x1aa18f(0x3c3)](this[_0x1aa18f(0x4c1)](), _0x1c9d91);
        case '4':
            var _0x1c9d91 = '';
            continue;
        }
        break;
    }
}

简化之后,很明显可以看出 captchaUuid 是 当前日期时间 + 18位随机字符串。

generateTimeFormat = function () {
    var current_time = new Date()
      , _0x2257b4 = function (_0x2bb897) {
        return +_0x2bb897 < 10 ? '0' + _0x2bb897 : _0x2bb897['toString']();
    };
    return current_time['getFullYear']()['toString']()
        + _0x2257b4(current_time['getMonth']() + 1)
        + _0x2257b4(current_time['getDate']())
        + _0x2257b4(current_time['getHours']())
        + _0x2257b4(current_time['getMinutes']())
        + _0x2257b4(current_time['getSeconds']());
}

getCaptchaUuid= function () {
     var random_str = '';
     var base_str = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
     var basestr_length = base_str['length'];
     for (var i = 0; i < 18; i++) {
                random_str += base_str['charAt'](Math['floor'](Math['random']() * basestr_length));
            }
     return generateTimeFormat() + random_str;
}
console.log(getCaptchaUuid());

注意:虽然 register 和 fverify 参数中也有 captchaUuid 值,但是后面两个请求的captchaUuid 与 conf 中的 captchaUuid 值是一样的,captchaUuid 值是在 conf请求前生成的,因此 若是在 register 和 fverify 中 定位 captchaUuid 时,才在 getCaptchaUuid 处打断点,是无法断住的。

4.2 文字点选验证

按照指定顺序点击图中文字
在这里插入图片描述

4.3 图标点选验证

按照指定顺序点击图中图标
在这里插入图片描述

4.4 语序点选验证

按照正常的成语语序 点选文字
在这里插入图片描述

4.5 空间推理验证

按照指示文字 完成空间推理
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值