js逆向-腾讯滑块collect参数

一、案例分析

  • 提示:此篇文章并没有解决整个滑块部分,如明文如何生成都未研究,只是在已有明文的基础下,去研究了jsvmp执行的流程与插桩的尝试过程,仅仅是思路过程学习记录
  • 网址如下,研究的是这个接口aHR0cHM6Ly9tYWlsLnFxLmNvbS8= 下的collect参数和vData参数
    在这里插入图片描述
    在这里插入图片描述

二、collect参数定位与分析

  • 搜索关键词collectdata定位,然后打上断点,然后滑动滑块,如图断住了
    在这里插入图片描述

  • console界面输出x()函数,如图即生成了collect参数
    在这里插入图片描述

  • 在console界面打印x函数,点击进入发现collect其实就是a.getData(!0)生成的
    在这里插入图片描述

  • 仅接着打印a.getData函数,即进入jsvmp的代码里,最终在return __TENCENT_CHAOS_VM(x, U, T, M, c, E, Y, B)这里返回collect参数
    在这里插入图片描述

  • 单步调试进入__TENCENT_CHAOS_VM函数,我们会发现在如图位置反复执行,然后我们在266行这里插桩JSON.stringify(j.slice(-2)),输出日志,以及网上日志查看,根据经验先大概的猜测,长数字转乱码小串拼接,乱码小串base64得到collect
    在这里插入图片描述
    在这里插入图片描述

  • 在反复调试的过程中,你会发现D是一个大数组,里面几乎都是函数,而U[w]决定了取哪个函数进行执行操作,而贯穿的j数组则是在j[j.length-2] 与 j.pop()反复的进行覆盖以及算术操作等,大致执行流程熟悉后,我们开始正式的插桩分析
    在这里插入图片描述

  • 第一次插桩打日志点,如下图,我是将线上的slide.js的js文件保存到本地为tencent.js,然后添加了部分插桩日志内容,然后用fiddler进行了替换输出
    在这里插入图片描述
    在这里插入图片描述

    j[j.length - 2] = j[j.length - 2] + j.pop()
    if(typeof j[j.length - 1] == "string"){
          
          
    	console.log("j栈的输出", j[j.length - 1]);
    }
    
  • 如图,刷新后,线上console界面输出如下,可以知道collect由4个超长的字符串拼接而成,console界面输出的collect将所有的"+"替换为空collect.replace(/\+/g, " ") ,则和请求参数界面一致
    在这里插入图片描述
    在这里插入图片描述

  • 第一组长串可知,超长串是由超长乱码串base64加密而得
    在这里插入图片描述

在这里插入图片描述

  • 超长的乱码串是由小的乱码串拼接而成,小的乱码串其实是由长数字转换而得
    在这里插入图片描述
    在这里插入图片描述

  • 第二次插桩打断点,可以知道 Ç^ÿ °>乱码小串是由这个类似String.fromCharCode.apply(String, [199, 16, 94, 255])转换而得,下面就是要知道[199, 16, 94, 255]这个数字是怎么来的

    "quality的输出", M[0][M[1]], M[0], F, quality
    

    在这里插入图片描述
    在这里插入图片描述

  • 第三次添加条件断点M[0]==='{"cd' ,然后跳到这里停住后,继续加其它的日志
    在这里插入图片描述

  • 第四次加如下这些日志,在& / >>, j[j.length - 2], ">>>", j.slice(-1), "result is", j[j.length - 2]>>> j.slice(-1)[0],以及一些其它的日志断点,这些日志断点建议等条件断点断住后,再开放这些日志断点输出
    在这里插入图片描述
    在这里插入图片描述

    "quality的输出", M[0][M[1]], M[0], F, quality
    "fit",fit, "F[0]", F[0]
    "shipment", shipment
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • [199, 16, 94, 255]的由来如图,至此我们得到第一个算法函数LongNumToCode,长数字转成乱码小串,接下来就是研究[-10612537,1051754885]这个长数字是怎么来的,这个是最难的部分,是由另一个长数字经过tea算法转换而得
    在这里插入图片描述

    function LongNumToCode(long_num){
          
          
        var offsets = [0, 8, 16, 24];
        var codes = [];
        for(var a of offsets){
          
          
            codes.push(long_num >> a & 255);
        }
        return String.fromCharCode.apply(String, codes);
    }
    
  • 接着前面的输出日志继续分析,如图得到第二个算法函数StrToLongNum,这里得到两个长数字[ 1684218491, 811285026 ],与我们前面需要的长数字不一致,继续分析[ 1684218491, 811285026 ]接下来是干什么了
    在这里插入图片描述
    在这里插入图片描述

    function StrToLongNum(str){
          
          
        var offsets = [0, 8, 16, 24];
        var long_num = 0;
        for (let i = 0; i < str.length; i++){
          
          
            long_num = long_num | (str.charCodeAt(i) << offsets[i]);
        }
        return long_num
    }
    
  • 继续分析,可以得到第二个算法函数tea加密算法,在图中会发现一个特征数字2654435769经常出现,此为tea加密算法 ,以及该大佬的文章也有说,还有逆向简史的大佬也有讲到,如图已知长数字[ 1684218491, 811285026 ],得到了新的长数字[-10612537,1051754885]
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    function teaEncryptBlock(num_lis, key){
          
          
        var num1 = num_lis[0];
        var num2 = num_lis[1];
        var sum = 0;
        // 1194941531 '+' [592134] 'result is' 1195533665
        // 1214603871 '+' [394760] 'result is' 1214998631
        key = [1195533665, 1214998631, 1416189259, 1481725512];
        var delta = 2654435769;
        for (var i = 0; i < 32; i++) {
          
          
            num1 += (((num2 << 4) ^ (num2 >>> 5)) + num2) ^ (sum + key[sum & 3]);
            // console.log("num1", num1)
            sum += delta;
            // console.log("sum", sum)
            num2 += (((num1 << 4) ^ (num1 >>> 5)) + num1) ^ (sum + key[(sum >> 11) & 3]);
            // console.log("num2", num2)
        }
        return [num1, num2];
    }
    
  • 将前面分析的算法函数进行梳理下,然后输出如下,与网页结果保持一致,至此collect参数分析完毕,但是这些明文/轨迹的生成未研究,也是最难的部分,感兴趣可以自行试试
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43411585/article/details/123810961