某鹅滑块验证码破解笔记

查看 151|回复 11
作者:null_null   
0x00 序言
很久之前就听说过VM加密,但一直对VM概念很模糊,于是最近便想去下VM壳相关的技术,但在网上各种帖子学习到的知识有限,不能很好的去了解VM壳的一些原理和机制,于是就在想去找个VM壳进行逆向,看看能不能去学习到些什么东西。
本次逆向的是某鹅基于JavaScript语言的一个栈式虚拟机,不得不说刚接触这个代码的时候着实看不懂写的是什么东西,可是随着慢慢的深入,越发觉得这个虚拟机犹如一个艺术品,很是奇妙。
下面就随着我一起一步步,揭开这个虚拟机的神秘面纱吧!
注:若有侵权,请联系我立即删除,本文只作为交流学习用途,一些关键信息已做相关处理。
0x01 准备工作
首先说明下我们的目的,验证码在滑动完成以后会向服务器发送一些数据,这些数据包含了一些必要或者非必要的信息。必要的信息如下:


image-20210910202439882.png (130.91 KB, 下载次数: 0)
下载附件
2021-10-18 13:53 上传

可以看到字段名是collect,根据字段名可以猜测到这个字段值是一些收集的数据,可能包含一些浏览器环境信息以及我们滑动滑块的轨迹或者是鼠标的移动轨迹这类的信息,另一个必要信息如下:


image-20210910202905631.png (11.83 KB, 下载次数: 0)
下载附件
2021-10-18 13:54 上传

以上两个加密字段值,是如何生成的,里面包含了一些什么数据,如何去模拟达到破解滑块的目的,便是此文章的目的。
0x02 定位加密点
通过浏览器控制台的搜索,我们试着搜索下这个collect字段:


image-20210910203451250.png (80.34 KB, 下载次数: 0)
下载附件
2021-12-22 19:56 上传

跟进去,在此处下断点:


image-20210910203537714.png (69.43 KB, 下载次数: 0)
下载附件
2021-12-22 19:57 上传

再次滑动,果不其然在这个地方断了下来:


image-20210910203711040.png (25.63 KB, 下载次数: 0)
下载附件
2021-12-22 19:57 上传

简单分析了下e的值,发现和我们提交的参数格式基本一致,所以collect应该就是在这个地方赋值的,接下来就是看看R()函数是怎么生成collect的,跟进R函数如下:


image-20210910203926637.png (35.19 KB, 下载次数: 0)
下载附件
2021-12-22 19:59 上传

现在跟到了getData这个函数,我们下断点,继续执行代码,让断点触发,然后到控制台打印了下a变量,a看起来像是一个接口,提供了一些函数:


image-20210910204229899.png (24.86 KB, 下载次数: 0)
下载附件
2021-12-22 19:59 上传

继续往上面找找,看看a是怎么来的,在上面几行找到了a的赋值:


image-20210910204412760.png (40.08 KB, 下载次数: 0)
下载附件
2021-10-18 13:57 上传

a = window.TDC
看起来是在window对象里面又定义了一个TDC对象,然后将TDC对象赋值给了a,现在让我们看看getData函数的实现,跟进来,就跟到了这个地方:
所以getData函数的实现应如下:
//getData实现
function k() {
        var B = A.slice(0);
        B[0] = [this],
        B[1] = [arguments],
        B[2] = [k];
        for (var M = 0; M
可能解释的有些不太清楚,我们先来看看下面的代码:
var E = []; //声明了一个空数组E,用来存放函数
(function TEST(){ //立即执行函数
    var rand = Math.random() //生成随机数
    console.log(rand)
    E.push(function (){ //将函数存入数组
        var test = rand;
        console.log(test) //打印上文生成的随机数
    })
    if(E.length > 1)return;
    TEST()
})()
E[0]()
E[1]()
运行结果如下:
0.5371786118718886
0.6474871625616907
0.5371786118718886
0.6474871625616907
从这里可以发现,随机数被保存了下来,所以可以通过这种方式去实现函数部分传参的保存,当函数被调用时,所需要的变量值未被销毁,仍可以进行访问使用,那么问题来了,为什么要通过这种方式进行函数调用呢,直接写一个函数去实现相应的功能不行吗?
这个问题就要随着我一步步分析,你就会明白为什么会这样写。
为了验证getData函数是不是通过上述地方进行调用,我们把代码复制过来,通过nodejs的环境来进行调用,为了模拟真实的浏览器环境,用到一个叫做jsdom的库。
jsdom介绍如下:

jsdom 是许多 Web 标准的纯 JavaScript 实现,特别是 WHATWG DOM和HTML标准,用于 Node.js。一般来说,该项目的目标是模拟足够多的 Web 浏览器子集,以用于测试和抓取真实的 Web 应用程序。

node环境下安装:
npm install jsdom
用法:
const jsdom = require("jsdom");
const {JSDOM} = jsdom;
const dom = new JSDOM(`Hello world
`);
window = dom.window;
document = window.document;
XMLHttpRequest = window.XMLHttpRequest;
完成环境模拟,我们就可以将代码复制到编辑器里面去,如下图所示:


image-20210929203518634.png (86.81 KB, 下载次数: 0)
下载附件
2021-10-18 13:58 上传

我们在代码末尾加上:
console.log(window.TDC)
打印结果如下:
{
  getInfo: [Function: M],
  setData: [Function: M],
  clearTc: [Function: M],
  getData: [Function: M] //getData函数已经能够进行调用了
}
调用getData函数:
console.log(window.TDC.getData())
结果如下:
e43rYszBdPpLFbYEnvf6EH423DMkVfmqhtQV%2BCnQMWEdGBJzm4MFSOGDFX0ykuQGqe4c1cxY5APK40WOd9u7mbdwXIQ1x9OBSgdVHmORAxmVEXILfudlFIYF4KW7ZuOdX9ixo4efmMqIViV1IKT%2B24mEOmUJ2xtr6ULKcsrp0Xg3GQkNZ7iWy2G87RaR5NpSgHnX6q8eD5UIoml8J6bqef1JDKK%2BW4iXKaj3j5PGwLo%2FqrW1 mWy%2BB0MSvS91m%2FYk%2BNtC79fF0pOuSvflUSrAAohWJXUgpP7b%2BTuue9zspkzK8nLSWZGjTc4sycUohsG5owCAZch4y%2FYdttQ4D4nFT4hWJXUgpP7bM3NuzmNY663gs%2FQ7BKUdIk9HX3mnJQOT%2FB2S9xc25mskD87Pieargmi4QVyC1l%2Bnr5VFrxOHLI%2FkcpgPZqPrbVoWKk8cGT03izOvvebVB7xzp4B06AdsZe 7Q%2FnP%2BALoM%2F3Q6Sp0JU7daFipPHBk9N1oWKk8cGT03mCh6%2FirnaBoh%2BZs4V9dDlA%3D%3D
在调用处下断点:


image-20210929204326642.png (14.59 KB, 下载次数: 0)
下载附件
2021-10-18 13:58 上传

进入调试模式,F7步入:


image-20210929204442157.png (65.45 KB, 下载次数: 0)
下载附件
2021-10-18 13:58 上传

可以看到函数进入到了前面我们分析的这个地方。接下来先对整个代码的结构进行分析。
0x03 代码结构分析
先把代码全部折叠,主要的函数是TENCENT_CHAOS_STACK函数,又把TENCENT_CHAOS_STACK函数下级进行展开,结构如下:
var __TENCENT_CHAOS_STACK = function() {
    function __TENCENT_CHAOS_VM(c, R, H, h, I, C, w, F) {...}
        function I(E) {...}
    return __TENCENT_CHAOS_VM.v = 0,
        __TENCENT_CHAOS_VM(0,
                           function(E){...}(["...",[...]]),
                           window)
        //TENCENT_CHAOS_VM传参分析:(0, 立即函数返回值, window)                  
}();
现在我们把这个立即函数单独提取出来运行:


image-20210929210108491.png (28.48 KB, 下载次数: 0)
下载附件
2021-10-18 13:59 上传

运行结果如下:


image-20210929210147252.png (33.44 KB, 下载次数: 0)
下载附件
2021-10-18 13:59 上传

其实这个运行结果可以看做是字节码,然后每一个字节码对应一个不同的操作或是数据,函数TENCENT_CHAOS_VM的作用就是解释并且执行字节码,TENCENT_CHAOS_VM函数的第一个传参是0,这个值代表PC寄存器,作用是指向下一个字节码的位置。
代码结构简化如下:


image-20210929211453882.png (48.88 KB, 下载次数: 0)
下载附件
2021-10-18 13:59 上传

现在我们知道了TENCENT_CHAOS_VM是用来解释并执行字节码的,现在让我们来看看TENCENT_CHAOS_VM的执行过程(其实到这一步各位读者可以自行去调试一下,更容易理解整个执行流程)
0x04 虚拟机执行过程
在函数入口下断点:


image-20211014213828123.png (20.49 KB, 下载次数: 0)
下载附件
2021-10-18 14:04 上传

进入调试模式,程序在断点处断下来,此时变量表如下:


image-20211014214141246.png (49.83 KB, 下载次数: 0)
下载附件
2021-10-18 14:04 上传

c是第一个被传入的变量,也就是PC变量,它指向下一个被执行字节码的位置,也就是第二个传入的变量(R,字节码)的第0个元素,即为7,我们将程序继续往下执行,来到这里:


image-20211014214818737.png (56.96 KB, 下载次数: 0)
下载附件
2021-10-18 14:05 上传

x部分指令如下:


image-20211014214856357.png (41.55 KB, 下载次数: 0)
下载附件
2021-10-18 14:05 上传

图片里面的"G为此次函数是否完成的标志",这里用"次"的原因是这个VM包含递归调用,也就是在这个函数里面又调用这个函数,我们现在知道这个函数是不停的执行字节码,PC是下一个被执行字节码或是数据的地址,那么就可以通过在不同的地方定义不同的操作,然后通过调用本函数,传入不同的PC,去完成不同的操作(也就是函数调用),通俗来讲就是和程序里面的函数偏移地址是一样的道理,通过偏移地址去找到函数,并执行函数。这个VM的第一个传参就是PC,所以可以通过定义好的函数偏移,去进行函数调用,函数的本质也是一堆指令的集合。
现在PC的值为0,上面说到对应的字节码是7:


image-20211014215952630.png (7.85 KB, 下载次数: 0)
下载附件
2021-10-18 14:05 上传

所以要执行x数组里面的第七条指令,跟进如下:


image-20211014220034306.png (46.02 KB, 下载次数: 0)
下载附件
2021-10-18 14:05 上传

h为栈,所有的数据都是通过栈来操作的,也就是把需要用到的数据存到这个栈中,然后需要用的时候取出来或者直接对栈元素进行操作h.length = R[c++]的含义是定义栈的长度,栈的长度为R[1],R(字节码)不但保存了指令,也保存了数据。
然后又回到循环的位置,执行下一个字节码:


image-20211014220230087.png (73.86 KB, 下载次数: 0)
下载附件
2021-10-18 14:06 上传

可以看到整个字节码的长度有四万多,一条一条的调试就不太现实了,现在就需要要进一步分析。
0x05 collect加密还原
在这些指令集中(x数组),包含了一个相加的指令:
h[h.length - 2] = h[h.length - 2] + h.pop()
一般字符串的拼接,都是直接相加,我们在这条指令后面,加一句console.log(h[h.length - 1]),将栈顶的数据打印出来看一看会不会有什么发现(代码最后记得加上console.log(window.TDC.getData())去调用加密):


image-20211014221745160.png (51.07 KB, 下载次数: 0)
下载附件
2021-10-18 14:06 上传

输出了很多整数,在继续往下面找,发现一个熟悉的变量:


image-20211014221847864.png (52.68 KB, 下载次数: 0)
下载附件
2021-10-18 14:06 上传

这个是tea加密的delta常量值乘以十,这个先留意一下,我们打印代码的时候,再加个判断,使控制台只打印字符串:
if(typeof h[h.length - 1] == "string"){
        console.log(h[h.length - 1])
}
打印的部分结果如下:
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,""
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other"
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",tel:1634221284
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",tel:1634221284,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8"
[1024
[1024,
[1024,768
[1024,768]
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768]
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,""
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",[]
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0,
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0,true
看样子是打印了一些环境参数,cd应该就是collectData的缩写,意为收集到的数据,但是在控制台找不到完整的json数据。
上面发现的delta常量,是tea加密的一个常量,tea加密的核心算法如下:
void EncryptTEA(unsigned int *firstChunk, unsigned int *secondChunk, unsigned int* key)
{
    unsigned int y = *firstChunk;
    unsigned int z = *secondChunk;
    unsigned int sum = 0;
    unsigned int delta = 0x9e3779b9;
    for (int i = 0; i > 5) + key[1]);
        z += ((y > 5) + key[3]);
    }
    *firstChunk = y;
    *secondChunk = z;
}
由于第一轮加密的时候sum值等于delta常量值,我们在加法指令处的代码改为:
h[h.length - 2] = h[h.length - 2] + h.pop()
if(typeof h[h.length - 2] == "number" && h[h.length - 2] == 0x9e3779b9){ //当加密结果为delta常量时打印bingo
        console.log("bingo")
}
并在console.log("bingo")处下断点,然后进行调试:
触发断点:


image-20211014224250603.png (108.34 KB, 下载次数: 0)
下载附件
2021-10-18 14:07 上传

可以看到h变量(栈)中有很多整数,我们通过javaScript写一个把整数转为字符串的代码:
function longsToStr(l) {
    var a = new Array(l.length);
    for (var i = 0; i >> 8 & 0xFF,
            l >>> 16 & 0xFF, l >>> 24 & 0xFF);
    }
    return a.join('');
}


image-20211014225614383.png (47.26 KB, 下载次数: 0)
下载附件
2021-10-18 14:08 上传

将h[3]中的两个整数还原得到一个类似原文的字符串:
longsToStr([741432155]) + longsToStr([842083377])
"[[1,1,12"
我们重新修改打印代码:
if(typeof h[h.length - 2] == "number" && h[h.length - 2] == 0x9e3779b9){ //当加密结果为delta常量时打印bingo
        console.log(longsToStr([h[3][0][0]]) + longsToStr([h[3][0][1]]))
}
打印结果如下:
[[1,1,12
]]
{"cd":[2
4,"about
:blank?r
and=1519
71362434
7","0-0-
0-24-*-*
-|-*",[]
,tel:1766882
96,[],0,
0,"",[],
0,0,0,1,
9,[],0,0
,tel:1634223
750,0,"M
ozilla/5
.0 (win3
2) Apple
WebKit/5
37.36 (K
HTML, li
ke Gecko
) jsdom/
17.0.0",
"top",99
9760772,
16342237
50,0,"?r
and=1512
99198633
4",0,"",
"other",
16342237
50,"UTF-
8",[1024
,768],0,
1,0,"",[
],0,true
,
,[],0,0,
["en-US"
,"en"],"
98k"],
"sd":{"o
d":"C"}}
看来加密前的明文大致是这样子,现在我们需要进一步确认这个tea加密是否为标准的tea加密,密钥是怎么生成的。
接下来就是一步步动态调试,一步步跟进,还原出加解密如下:
function hex2int(hex) {
    var len = hex.length, a = new Array(len), code;
    for (var i = 0; i >> 8 & 0xFF,
            l >>> 16 & 0xFF, l >>> 24 & 0xFF);
    }
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency in IE
}
Base64.prototype.encode = function (input) {
    var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
    //input = this._utf8_encode(input);
    while (i > 2;
        enc2 = ((chr1 & 3) > 4);
        enc3 = ((chr2 & 15) > 6);
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }
        output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
    }
    return output;
}
Base64.prototype.decode = function (input) {
    var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    while (i > 4);
        chr2 = ((enc2 & 15) > 2);
        chr3 = ((enc3 & 3) >> 5)) + y) ^ (sum + Key[sum & 3] + Key[4]);
        }else if((sum & 3) == Key[7]){
            x += (((y >> 5)) + y) ^ (sum + Key[sum & 3] + Key[5]);
        }else{
            x += (((y >> 5)) + y) ^ (sum + Key[sum & 3]);
        }
        sum += delta;
        if(((sum >> 11) & 3) == Key[6]){
            y += (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]  + Key[4]);
        }else if(((sum >> 11) & 3) == Key[7]){
            y += (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3] + Key[5]);
        }else{
            y += (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]);
        }
    }
    return [x, y];
}
function DecryptBlock(DecryData, Key){
    var x = DecryData[0];
    var y = DecryData[1];
    var sum = 0x9E3779B9 * 32;
    var delta = 0x9E3779B9;
    for (var i = 0; i > 11) & 3) == Key[6]){
            y -= (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]  + Key[4]);
        }else if(((sum >> 11) & 3) == Key[7]){
            y -= (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3] + Key[5]);
        }else{
            y -= (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]);
        }
        sum -= delta;
        if(((sum & 3) == Key[6]) ){
            x -= (((y >> 5)) + y) ^ (sum + Key[sum & 3] + Key[4]);
        }else if((sum & 3) == Key[7]){
            x -= (((y >> 5)) + y) ^ (sum + Key[sum & 3] + Key[5]);
        }else{
            x -= (((y >> 5)) + y) ^ (sum + Key[sum & 3]);
        }
    }
    return [x, y];
}
var teaDecrypt = function (msg, Key){
    var res = new Base64().decode(msg);
    var rounds = res.length >> 3;
    var tmp;
    var final = "";
    for(var i = 0; i > 3;
    for(var i = 0; i
经过还原代码发现tea加密有变,具体的如上面的代码所示,正常的tea加密key为16字节,也就是4个int,但是这个变种tea算法在进行加解密时引入了额外8个字节的“密钥”,两个判断变量,判断是否将额外密钥加入计算。
通过测试发现每次密钥都不同,如何得到原本的16字节key,8个额外的key以及判断变量?在这里我想过一个通过tea加密函数入口地址的偏移去计算密钥的地址或是通过一些固定的特征码计算key的地址,但可惜的是只能拿到基本的16字节的地址,额外密钥以及判断变量则不能拿到,不同的滑块对应的不通源码,里面的字节码都会有变化,因此这种方法便放弃了。
加密在执行的时候,肯定会从栈里面取出这些变量,因此我就想到可以通过找到一个代码执行到某一句的时候,栈里面刚好有我们需要的key,然后我们将这些key进行返回。基于这个想法,我写了一个正则表达式去匹配整个代码,并对代码的加法指令进行修改,让代码字节把key吐出来,脚本如下:
function dec(jsText, cipherTxt){
    jsText = jsText.replace(/TypeError\(.*?\)/g,"\"error\"");
    var pos = jsText.indexOf("TENCENT_CHAOS_VM");
    var PC = (pos += 17,jsText.slice(pos, pos + 1));
    var PB = (pos += 2,jsText.slice(pos, pos + 1));
    var STACK = (pos += 4,jsText.slice(pos, pos + 1));
    var HANDLE = /var [A-Za-z]=\[function/.exec(jsText)[0].slice(4,5);
    var COD = /try\{for\(var [A-Za-z]=/.exec(jsText)[0].slice(12,13);
    jsText = "var key;var flag=0;" + jsText.replace(COD+"="+HANDLE+"["+PB+"["+PC+"++]]();","{if(flag==1){return key;}"+COD+"="+HANDLE+"["+PB+"["+PC+"++]]();"+"}").replace("R[R.length-2]=R[R.length-2]+R.pop()".replace(/R/g,STACK),'if((R[R.length-2]==0x9E3779B9)||(R[R.length-1]==0x9E3779B9)){for(var i=0;i1000){key=R[0];break;}};key.push(PB[PB.indexOf(0x9E3779B9) - 19]);key.push(PB[PB.indexOf(0x9E3779B9) - 53]);key.push(PB[PB.indexOf(0x9E3779B9) - 6]);key.push(PB[PB.indexOf(0x9E3779B9) + 15]);flag=1;return key;}R[R.length-2]=R[R.length-2]+R.pop()'.replace(/R/g,STACK).replace(/PB/g,PB));
    var tmpKey = eval(jsText+"window.TDC.getData(!0)")
    return teaDecrypt(cipherTxt, tmpKey);//teaDecrypt和上面的代码一致
}
将tea算法与这个dec进行整合,我们就能实现对collect的解密了,测试如下:


image-20211014232739353.png (43.4 KB, 下载次数: 0)
下载附件
2021-10-18 14:08 上传

返回值如下:
{"cd":["https://ui.ptlogin2.qq.com/?rand=tel:1512991986334",0,true,[],0,["zh-CN","zh"],0,1630507225,360,640,"360-640-640-24-*-*-|-*",5,[],0,[],0,[],2,                      [[1,1,12]]              ,159,1630507226,"Win","98k","",0,"","Mozilla/5.0 (Linux;
Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Mobile Safari/537.36",0,1084792919,0.746999979019165,[],0,0,"UTF-8",1467230630,1630507225,[],[345,345],0,24,"7688915523684241625","true",2,1023],
        "sd":{"od":"C"}}
现在collectData的解密工作已完成,接下来我们需要对解密后的代码进行分析
0x05 collect数据分析以及生成
其中cd是收集到的数据,用一个数组进行保存,而经过多次测试后发现,数组里面的数据顺序是不固定的,也就是一个滑块对应着一种顺序,所以如果我们要通过明文伪造加密数据,还需要知道数据存放的顺序,在庞大的字节码中找到数据存放的数据也是一个很大的工程,但是如果是不伪造数据,通过jsdom的环境生成出来的加密数据又过不去滑块。思前想后,我想到一个办法,那就是通过正则匹配来对代码进行改造,找到不同数据生成的地方,对生成后的数据进行修改(对照正常的数据),所以接下来就是通过不断的调试代码,找到代码是如何生成的,找到生成代码的地方,对代码进行修改。如果修改有效,制定正则匹配方案。如此循环,直到生成出来的数据和浏览器抓包得到的数据差不多,能过滑块的环境识别,那么就成功了。然后将整个过程封装成一个函数,传入js代码,自动修改代码,并且eval运行代码得到collect。
这里我就不分析每个数据的意义了,只是提供大概的思路以及方向。如果要定位到某个代码的生成地方,可以先看到在我们进行数据解密的时候,拿到的一些数据:
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8",[1024,768]
比如上面的数据,第一次打印的时候,还没有[1024,768]这个数据,那么我们就可以在这个数据打印之前,也就是打印完这句话以后,进行单步调试:
{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",
"other",1634221284,"UTF-8"
通过这种方法,就能跟踪到[1024,768]的来源。当然这只是一种方法,还有别的定位方法,就等着大家去发现了。
调试这里面坑很多,不但要定位生成的地方、制定正则匹配规则,还需要不断去加密提交到滑块服务器去验证生成的数据能不能用,总之就是需要耐心。
破解的核心思路总结起来就是:正则匹配(或是AST)修改特征代码到可运行状态,eval进行调用得到目标值。
0x06 vData参数分析
上次我们讲到了collect的加密方式以及怎么去生成这个参数的思路,现在我们来讲讲另一个加密参数,vData


image-20211015201512985.png (4.62 KB, 下载次数: 0)
下载附件
2021-10-19 22:42 上传

定位过程就不再赘述了,本小节的目的主要是讨论vData的生成方式。
vData是由vm-slide.js生成的,代码结构和生成collect参数的js代码一致,代码如下:
var __TENCENT_CHAOS_STACK = function() {
    function __TENCENT_CHAOS_VM(g, m, U, n, E, F, Y, c) {
        var A = !n;
        g = +g,
        m = m || [0],
        n = n || [[this], [{}]],
        E = E || {};
        var w, C = [], K = null;
        function p() {
            return function(A, C, K) {
                return new (Function.bind.apply(A, C))
            }
            .apply(null, arguments)
        }
        Function.prototype.bind || (w = [].slice,
        Function.prototype.bind = function(A) {
            if ("function" != typeof this)
                throw new TypeError("bind101");
            var C = w.call(arguments, 1)
              , K = C.length
              , p = this
              , Q = function() {}
              , B = function() {
                return C.length = K,
                C.push.apply(C, arguments),
                p.apply(Q.prototype.isPrototypeOf(this) ? this : A, C)
            };
            return this.prototype && (Q.prototype = this.prototype),
            B.prototype = new Q,
            B
        }
        );
        var Q = [function() {
            n.push(n[m[g++]][0])
        }
        , function() {
            var A, C = [];
            for (A in n.pop())
                C.push(A);
            n.push(C)
        }
        , function() {
            var A = m[g++]
              , C = A ? n.slice(-A) : [];
            n.length -= A;
            A = n.pop();
            n.push(A[0][A[1]].apply(A[0], C))
        }
        , function() {
            n.push([n.pop(), n.pop()].reverse())
        }
        , function() {
            n.push("")
        }
        , function() {
            n.pop()
        }
        , function() {
            g = m[g++]
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] ^ n.pop()
        }
        , function() {
            n.push(m[g++])
        }
        , , function() {
            n[n.length - 1] += String.fromCharCode(m[g++])
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] & n.pop()
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] == n.pop()
        }
        , function() {
            n[n.length - 1] = U[n[n.length - 1]]
        }
        , , function() {
            n[n.length - 1].length ? n.push(n[n.length - 1].shift(), !0) : n.push(undefined, !1)
        }
        , function() {
            return !0
        }
        , function() {
            n.push(undefined)
        }
        , , , function() {
            n[n.length - 2] = n[n.length - 2] + n.pop()
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] - n.pop()
        }
        , , function() {
            n.push(!n.pop())
        }
        , function() {
            var A = n[n.length - 2];
            A[0][A[1]] = n[n.length - 1]
        }
        , function() {
            var A = m[g++]
              , C = A ? n.slice(-A) : [];
            n.length -= A,
            C.unshift(null);
            A = n.pop();
            n.push(p(A[0][A[1]], C))
        }
        , , , function() {
            n[n.length - 2] = n[n.length - 2] === n.pop()
        }
        , , , function() {
            n[n.length - 2] = n[n.length - 2] > n.pop()
        }
        , function() {
            n.push([U, n.pop()])
        }
        , function() {
            K = null
        }
        , , function() {
            C.push([m[g++], n.length, m[g++]])
        }
        , function() {
            n[n[n.length - 2][0]][0] = n[n.length - 1]
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] % n.pop()
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] / n.pop()
        }
        , function() {
            n.push(n[n.length - 1])
        }
        , function() {
            n.length = m[g++]
        }
        , function() {
            var A = n.pop()
              , C = n.pop();
            n.push([C[0][C[1]], A])
        }
        , function() {
            var A = m[g++];
            n[A] = n[A] === undefined ? [] : n[A]
        }
        , , , function() {
            n.push(null)
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] >> n.pop()
        }
        , function() {
            n.push([m[g++]])
        }
        , , function() {
            C.pop()
        }
        , function() {
            n[n.length - 1] = m[g++]
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] = n.pop()
        }
        , function() {
            n.push(n[n.pop()[0]][0])
        }
        , function() {
            var A = m[g++]
              , C = n[n.length - 2 - A];
            n[n.length - 2 - A] = n.pop(),
            n.push(C)
        }
        , , function() {
            var A = m[g++]
              , C = A ? n.slice(-A) : [];
            n.length -= A,
            n.push(n.pop().apply(U, C))
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] * n.pop()
        }
        , function() {
            n[n.length - 2] = n[n.length - 2] >>> n.pop()
        }
        ];
        for (0; ; )
            try {
                for (var B = !1; !B; )
                    B = Q[m[g++]]();
                if (0,
                K)
                    throw K;
                return A ? (n.pop(),
                n.slice(3 + __TENCENT_CHAOS_VM.v)) : n.pop()
            } catch (I) {
                0;
                var o = C.pop();
                if (o === undefined)
                    throw I;
                K = I,
                g = o[0],
                n.length = o[1],
                o[2] && (n[o[2]][0] = K)
            }
    }
    function E(A) {
        for (var C, K, p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split(""), Q = String(A).replace(/[=]+$/, ""), B = 0, w = 0, g = ""; K = Q.charAt(w++); ~K && (C = B % 4 ? 64 * C + K : K,
        B++ % 4) && (g += String.fromCharCode(255 & C >> (-2 * B & 6))))
            K = function(A, C, K) {
                if ("function" == typeof Array.prototype.indexOf)
                    return Array.prototype.indexOf.call(A, C, K);
                var p;
                if (null == A)
                    throw new TypeError('"array" is null or not defined');
                var Q = Object(A)
                  , B = Q.length >>> 0;
                if (0 == B)
                    return -1;
                if (B
在函数调用处下断点:


image-20211019202756322.png (27.94 KB, 下载次数: 0)
下载附件
2021-10-19 22:53 上传

移动滑块,触发断点,其中K参数(PC,此处为调用函数的地址)和A参数(传入参数)分别为:


image-20211019203024158.png (37.48 KB, 下载次数: 0)
下载附件
2021-10-19 22:54 上传

目前首要的是考虑怎么去拿到vData的加密方式,我们再将密文进行解密,分析里面的数据,会更直观,这次我们选择和collect一样的处理方式,就是通过修改代码,让他打印日志信息,暂且将这种行为称之为hook。
我们选择对加法指令进行hook,并查看日志,具体操作如下(这里直接通过浏览器开发者工具进行操作,并没有选择node环境模拟,原因是因为此VM代码涉及到网络请求,选择开发者工具直接进行操作会简单很多):
(1)、首先找到加法指令所在的行(可以看到是89行):


image-20211019203715106.png (27.03 KB, 下载次数: 0)
下载附件
2021-10-19 22:43 上传

(2)在90行(指令执行完成处)行标处右键,选择Add logpoint...:


image-20211019204215073.png (26.75 KB, 下载次数: 0)
下载附件
2021-10-19 22:43 上传

(3)输入n[n.length - 1],然后回车:


image-20211019204337071.png (19.26 KB, 下载次数: 0)
下载附件
2021-10-19 22:44 上传

hook代码就插入完成了,当运行了加法指令时,就会将栈顶的值打印出来,也就是相加以后的结果。
我们让代码执行,控制台就自动对代码进行了打印,打印的前部分结果如下:
1
VM171:1 2
VM172:1 3
VM173:1 4
VM174:1 5
VM175:1 6
VM176:1 7
VM177:1 8
VM178:1 9
VM179:1 10
VM180:1 11
VM181:1 12
VM182:1 13
VM183:1 14
VM184:1 15
VM185:1 16
VM186:1 17
VM187:1 18
VM188:1 19
VM189:1 20
VM190:1 21
VM191:1 22
VM192:1 23
VM193:1 24
VM194:1 25
VM195:1 26
VM196:1 27
VM197:1 28
VM198:1 29
VM199:1 30
VM200:1 31
VM201:1 tlg=(.*)
VM202:1 1
VM203:1 2
VM204:1 3
VM205:1 4
VM206:1 1
VM207:1 2
VM208:1 3
VM209:1 4
VM210:1 5
VM211:1 6
VM212:1 7
VM213:1 8
VM214:1 9
VM215:1 10
VM216:1 11
VM217:1 12
VM218:1 13
VM219:1 sess=(.*)
VM220:1 P
VM221:1 1
VM222:1 Ps
VM223:1 2
VM224:1 Psl
VM225:1 3
VM226:1 PslP
VM227:1 4
VM228:1 1
VM229:1 2
VM230:1 3
VM231:1 4
VM232:1 5
VM233:1 6
VM234:1 7
VM235:1 1
VM236:1 8
VM237:1 1
VM238:1 2
VM239:1 9
VM240:1 1
VM241:1 2
VM242:1 3
VM243:1 4
VM244:1 10
VM245:1 11
VM246:1 11,
VM247:1 11,tdc,slide,vm
VM248:1 ss=
VM249:1 ss=11%2Ctdc%2Cslide%2Cvm
VM250:1 1
VM251:1 env=
VM252:1 env=0
VM253:1 2
VM254:1 py=
VM255:1 py=0
VM256:1 3
VM257:1 inf=
VM258:1 inf=iframe
VM259:1 4
VM260:1 key=
VM261:1 key=PslP
VM262:1 5
VM263:1 cLod=
VM264:1 cLod=loadTDC
VM265:1 6
VM266:1 tp=
VM267:1 tp=5547380864951241219
VM268:1 7
VM269:1 version=
VM270:1 version=2
VM271:1 8
VM272:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2k
VM273:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kk
VM274:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkk
VM275:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkk
VM276:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkk
VM277:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkk
VM278:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkk
VM279:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkkk
VM280:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkkkk
VM281:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkkkkk
VM282:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkkkkkk
VM283:1 0
VM284:1 1
VM285:1 4
VM286:1 2
VM287:1 8
VM288:1 3
VM289:1 12
VM290:1 4
2VM291:1 5
VM293:1 9
VM294:1 6
VM295:1 13
VM296:1 7
VM297:1 1
VM298:1 8
VM299:1 10
VM300:1 9
VM301:1 14
VM302:1 10
VM303:1 2
VM304:1 11
VM305:1 6
VM306:1 12
VM307:1 15
VM308:1 13
VM309:1 3
VM310:1 14
VM311:1 7
VM312:1 15
VM313:1 11
VM314:1 16
VM315:1 s1t2%dCscs=2l1C%
2VM316:1 16
VM318:1 1
VM319:1 20
VM320:1 2
VM321:1 24
VM322:1 3
VM323:1 28
VM324:1 4
VM325:1 21
VM326:1 5
VM327:1 25
VM328:1 6
VM329:1 29
VM330:1 7
VM331:1 17
VM332:1 8
VM333:1 26
VM334:1 9
VM335:1 30
VM336:1 10
VM337:1 18
VM338:1 11
VM339:1 22
VM340:1 12
VM341:1 31
VM342:1 13
VM343:1 19
VM344:1 14
VM345:1 23
VM346:1 15
VM347:1 27
VM348:1 16
VM349:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mv
2VM350:1 32
VM352:1 1
VM353:1 36
VM354:1 2
VM355:1 40
VM356:1 3
VM357:1 44
VM358:1 4
VM359:1 37
VM360:1 5
VM361:1 41
VM362:1 6
VM363:1 45
VM364:1 7
VM365:1 33
VM366:1 8
VM367:1 42
VM368:1 9
VM369:1 46
VM370:1 10
VM371:1 34
VM372:1 11
VM373:1 38
VM374:1 12
VM375:1 47
VM376:1 13
VM377:1 35
VM378:1 14
VM379:1 39
VM380:1 15
VM381:1 43
VM382:1 16
VM383:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=a
2VM384:1 48
VM386:1 1
VM387:1 52
VM388:1 2
VM389:1 56
VM390:1 3
VM391:1 60
VM392:1 4
VM393:1 53
VM394:1 5
VM395:1 57
VM396:1 6
VM397:1 61
VM398:1 7
VM399:1 49
VM400:1 8
VM401:1 58
VM402:1 9
VM403:1 62
VM404:1 10
VM405:1 50
VM406:1 11
VM407:1 54
VM408:1 12
VM409:1 63
VM410:1 13
VM411:1 51
VM412:1 14
VM413:1 55
VM414:1 15
VM415:1 59
VM416:1 16
VM417:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=aesc=lLlyoo=PaP&d
2VM418:1 64
VM420:1 1
VM421:1 68
VM422:1 2
VM423:1 72
VM424:1 3
VM425:1 76
VM426:1 4
VM427:1 69
VM428:1 5
VM429:1 73
VM430:1 6
VM431:1 77
VM432:1 7
VM433:1 65
VM434:1 8
VM435:1 74
VM436:1 9
VM437:1 78
VM438:1 10
VM439:1 66
VM440:1 11
VM441:1 70
VM442:1 12
VM443:1 79
VM444:1 13
VM445:1 67
VM446:1 14
VM447:1 71
VM448:1 15
VM449:1 75
VM450:1 16
VM451:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=aesc=lLlyoo=PaP&dd&53t58T40Dp8C=7
2VM452:1 80
VM454:1 1
VM455:1 84
VM456:1 2
VM457:1 88
VM458:1 3
VM459:1 92
VM460:1 4
VM461:1 85
VM462:1 5
VM463:1 89
VM464:1 6
VM465:1 93
VM466:1 7
VM467:1 81
VM468:1 8
VM469:1 90
VM470:1 9
VM471:1 94
VM472:1 10
VM473:1 82
VM474:1 11
VM475:1 86
VM476:1 12
VM477:1 95
VM478:1 13
VM479:1 83
VM480:1 14
VM481:1 87
VM482:1 15
VM483:1 91
VM484:1 16
VM485:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=aesc=lLlyoo=PaP&dd&53t58T40Dp8C=7642v81e49r94s51&
2VM486:1 96
VM488:1 1
VM489:1 100
VM490:1 2
VM491:1 104
VM492:1 3
VM493:1 108
VM494:1 4
VM495:1 101
VM496:1 5
VM497:1 105
VM498:1 6
VM499:1 109
VM500:1 7
VM501:1 97
VM502:1 8
VM503:1 106
VM504:1 9
VM505:1 110
VM506:1 10
VM507:1 98
VM508:1 11
VM509:1 102
VM510:1 12
VM511:1 111
VM512:1 13
VM513:1 99
VM514:1 14
VM515:1 103
VM516:1 15
VM517:1 107
VM518:1 16
VM519:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=aesc=lLlyoo=PaP&dd&53t58T40Dp8C=7642v81e49r94s51&i2kkkkkokknkk=kk
VM520:1 112
VM521:1 1
VM522:1 1
VM523:1 2
VM524:1 3
VM525:1 4
VM526:1 1
VM527:1 2
VM528:1 1
VM529:1 2
VM530:1 3
VM531:1 4
VM532:1 2
VM533:1 3
VM534:1 1
VM535:1 2
VM536:1 3
VM537:1 4
VM538:1 3
VM539:1 4
VM540:1 1
VM541:1 2
VM542:1 3
VM543:1 4
2VM544:1 4
VM546:1 1
VM547:1 2
VM548:1 3
VM549:1 4
VM550:1 4
VM551:1 8
VM552:1 1
VM553:1 2
VM554:1 3
VM555:1 4
VM556:1 2867838358
VM557:1 845493299
VM558:1 -889275624
VM559:1 -2336555152
VM560:1 2654435769
VM561:1 4338529007
VM562:1 3915755972
VM563:1 2054546322
VM564:1 3466441244
VM565:1 -2149118810
VM566:1 -2190016853
VM567:1 5308871538
可以看到里面有一些有用的信息,如下:
VM201:1 tlg=(.*) //正则表达式,取出tlg
VM219:1 sess=(.*) //正则表达式,取出tlg
VM282:1 ss=11%2Ctdc%2Cslide%2Cvm&env=0&py=0&inf=iframe&key=PslP&cLod=loadTDC&tp=5547380864951241219&version=2kkkkkkkkkkk //很可能是加密之前的明文,而多出来的k也应该是补齐方式
VM519:1 s1t2%dCscs=2l1C%i2&=Ce0dn&evp%mvyiimnfe=r&0fk&=aesc=lLlyoo=PaP&dd&53t58T40Dp8C=7642v81e49r94s51&i2kkkkkokknkk=kk //被乱序的字符串
VM560:1 2654435769 //熟悉的delta常量
既然找到了delta常量,那么我们只需要添加一个条件断点,当栈顶值为delta常量时断点断下来,操作和日志断点类似,右键的时候选择Add conditional breakpoint...


image-20211019211318256.png (13.03 KB, 下载次数: 0)
下载附件
2021-10-19 22:44 上传

添加条件n[n.length - 1]==2654435769:


image-20211019211419211.png (20.89 KB, 下载次数: 0)
下载附件
2021-10-19 22:44 上传

然后滑动滑块,断点断下来,此时PC(对应__TENCENT_CHAOS_VM函数第一个传参,我这里变量名是g)的值是15355:


image-20211019211706995.png (33.58 KB, 下载次数: 0)
下载附件
2021-10-19 22:45 上传

现在我们将此时代码的PC值拿到了,现在我们要考虑如何将密钥取出来,在什么地方可以取得密钥。由于这个地方的tea加密我们不确定是不是被魔改过的,所以也只能老老实实的调试,将每一步进行的操作记录下来,还原成JavaScript代码,调试也没有什么特别的技巧,最重要的还是耐心,核心代码还原如下(固定密钥):
function EncryptBlock(EncryData){
    var Key = [845493299, 812005475, 825582135, 1684093238];
    var x = EncryData[0];
    var y = EncryData[1];
    var sum = 0;
    var delta = 0x9E3779B9;
    for (var i = 0; i >> 5)) + y) ^ (sum + Key[sum & 3]);
        sum += delta;
        y += (((x >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]);
    }
    return [x, y];
}
根据加密代码,反推得到解密代码:
function DecryptBlock(DecryData){
    var Key = [845493299, 812005475, 825582135, 1684093238];
    var x = DecryData[0];
    var y = DecryData[1];
    var sum = 0x9E3779B9 * 32;
    var delta = 0x9E3779B9;
    for (var i = 0; i >> 5)) + x) ^ (sum + Key[(sum >> 11) & 3]);
        sum -= delta;
        x -= (((y >> 5)) + y) ^ (sum + Key[sum & 3]);
    }
    return [x, y];
}
将两段代码替换collect的加解密函数即可对密文进行解密.
现在我们来解决被乱序的字符串的算法:
字符串乱序一般都会有一个映射表,可参考以下代码:
var msg = "0123"
var map = [3,2,1,0]
var res = ""
var mlength = msg.length
for(var i = 0; i
我们对charAt函数进行hook,代码如下(直接复制后放在控制台回车即可):
var hookCharAt = String.prototype.charAt;
String.prototype.charAt = function (index) {
    var res = hookCharAt.call(this, index)
    console.log(this, index)
    return res
}
hook日志如下:
String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 1
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 7
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 8
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 4
VM22081:4 String {"0abcdefghijklmnop"} 11
//乱序从这里开始
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 0
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 4
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 8
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 12
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 5
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 9
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 13
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 1
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 10
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 14
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 2
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 6
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 15
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 3
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 7
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 11
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 16
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 20
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 24
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 28
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 21
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 25
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 29
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 17
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 26
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 30
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 18
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 22
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 31
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 19
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 23
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 27
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 32
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 36
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 40
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 44
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 37
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 41
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 45
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 33
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 42
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 46
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 34
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 38
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 47
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 35
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 39
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 43
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 48
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 52
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 56
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 60
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 53
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 57
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 61
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 49
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 58
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 62
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 50
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 54
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 63
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 51
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 55
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 59
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 64
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 68
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 72
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 76
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 69
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 73
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 77
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 65
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 74
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 78
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 66
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 70
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 79
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 67
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 71
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 75
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 80
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 84
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 88
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 92
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 85
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 89
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 93
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 81
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 90
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 94
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 82
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 86
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 95
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 83
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 87
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 91
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 96
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 100
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 104
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 108
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 101
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 105
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 109
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 97
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 106
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 110
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 98
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 102
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 111
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 99
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 103
VM22081:4 String {"py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0kkkkkkkkkkk"} 107
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 17
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 46
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 6
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 39
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 16
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 45
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 41
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 13
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 60
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 38
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 15
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 17
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 47
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 62
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 5
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 54
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 13
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 18
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 0
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 40
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 19
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 3
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 4
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 4
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 15
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 25
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 16
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 34
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 50
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 0
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 14
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 34
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 8
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 38
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 39
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 40
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 63
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 35
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 61
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 28
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 7
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 8
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 52
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 24
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 44
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 60
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 24
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 52
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 9
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 11
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 10
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 51
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 34
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 20
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 7
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 49
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 30
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 41
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 0
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 40
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 32
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 41
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 59
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 28
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 38
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 6
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 23
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 2
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 24
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 22
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 9
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 6
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 28
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 11
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 15
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 46
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 19
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 36
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 41
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 55
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 58
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 16
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 55
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 2
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 22
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 13
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 33
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 7
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 30
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 38
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 11
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 3
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 60
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 43
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 8
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 30
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 39
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 26
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 30
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 21
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 10
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 12
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 14
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 35
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 21
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 59
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 3
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 19
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 25
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 2
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 28
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 62
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 0
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 32
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 7
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 1
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 15
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 45
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 17
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 57
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 19
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 29
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 6
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 46
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 10
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 14
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 30
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 9
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 58
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 16
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 48
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 46
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 37
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 32
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 64
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 64
可以看到,index被打印了出来,其中String {"0abcdefghijklmnop"} 11这个charAt的结果刚好是字母k,对应明文的padding,明文py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2…tp=7250156632690052586&version=2&env=0的长度为101,补齐了11个字符,补齐的码表为0abcdefghijklmnop,补齐后长度为16的倍数,所以应该是以16个字符为一轮进行乱序,所以我们只需要得到前16位的index,就能还原乱序,正序算法,算法还原如下:
function seqEncode(msg){
    var tmp = msg.length % 16;
    var ch = "0abcdefghijklmnop".charAt(tmp)
    while(tmp&&(16 - tmp)){
        msg += ch;
        tmp++;
    }
    var keyMap = [0, 4, 8, 12, 5, 9, 13, 1, 10, 14, 2, 6, 15, 3, 7, 11];
    tmp = msg.length >> 4;
    var res = "";
    for(var i = 0; i > 4;
    var res = "";
    for(var i = 0; i
接下来先看到最后一段:
VM22081:4 String {"GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY"} 48
其中GV5yc1_twaSpHPOE7R3jv9fqC2L-0TxMi4FuolBAbQeIgJU*XzZKWkDNh6n8dsrmY为base64码表,将这个base64码表对标准的base64编码码表进行替换,然后将密文解码,再解密,再正序,发现可以还原到最初的明文,加密部分就完成了。
现在进行明文参数分析,完整的明文如下:
py=0&cLod=loadTDC&inf=iframe&ss=11%2Ctdc%2Cslide%2Cvm&key=0T3E&tp=7250156632690052586&version=2&env=0kkkkkkkkkkk
现在应该就只剩下最后的key字段,key=0T3E。
通过上面的hook日志可以发现,前几行:
String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 1
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 7
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 8
VM22081:4 String {"s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**"} 4
1784实际上对应提交参数里面的tlg,这个参数为collect的长度,s07MEo6T3CWctUHFfxqCxvdirgIfUxLEAMZ-WzFaOH4dcvrWUM…q_k1pclUMwrBvVe5HK4zeAhCIsxn8WHMOc4VKWJwJ4X-U-Q**正好是服务器返回参数sess,所以key的算法还原如下:
function getKey(sess,tlg){
    tlg = tlg + "";
    var length = tlg.length;
    var res = "";
    for(var i = 0; i
0x07 结束语
至此,两个核心参数的加密就还原完成了,剩下的就是模拟参数生成,就能实现对验证码进行破解。其中这个滑块并没有对滑动数据以及鼠标移动数据进行相关校验,所以为空值也能过去,重点是collect里面的环境参数的校验以及还原。从刚开始接触这个vm到滑块的自动破解大概一共用了四五天左右,对jsvmp的了解又更深了一些,特别是执行流程和一些核心的设计思想。打算在近期内看看能不能研发一款js代码的虚拟化工具出来,如果有什么成果,会再次与大家分享!

下载次数, 函数

minibeetuaman   

研究JSVMP的文章不多,期待后续!
sunnyvv512   

前面图片加载不了
w565648   

collect在哪加密的啊   完全靠猜 猜出来的加密公式吗
null_null
OP
  

各位的图片能加载吗 好像图床出了点问题了
zx2000   

太厉害了,看不懂
dyanmix   

不明觉厉
放手一搏09   

坐等下一贴的更新!
qqaz1026940566   

坐等下一贴的更新!!
yu357708827   

很厉害,技术文章..支持一下
您需要登录后才可以回帖 登录 | 立即注册