首页
社区
课程
招聘
[原创]akamai参数简单分析---mst
发表于: 22小时前 150

[原创]akamai参数简单分析---mst

22小时前
150

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!

1、参数分析小笔记

mst:
    kevl: 1, 第三次请求中数值会变
    mevl: 32,第三次请求中数值会变
    devl和dmvl: 0, 第三次请求中数值会变和dme、doe有关联

    sts:时间戳
    tovl:等于ajr的totVel
    kc: 0, 第三次请求为1
    mc:0, 第三次请求中为鼠标轨迹组数
    ww8:0, 第三次请求中数值会变
    jsrf1和jsrf2:通过时间戳计算得到的长度为2的数组

    delt和ssts:ajr生成逻辑中deltaTimestamp

    dvc: vmp中(参数1是delt,参数2是ajr,参数3是请求轮次(0、1、2),参数4是tovl)


2、mst参数分析

mst需要关注的就dd2、jsrf1、jsrf2、dvc,其中的难点就是dvc的jsvmp。


把代码还原一下,也可以直接在作用域里面找一下,快速定位生成位置。



jsrf1、jsrf2就是通过计算时间戳得到,跟进XP2函数,连混淆都没有,直接复制就可以了。

var SWT = function (zYT) {
    var Y4 = zYT[0] - zYT[1];
    var RmT = zYT[2] - zYT[3];
    var A4 = zYT[4] - zYT[5];
    var SKT = S6["Math"]["sqrt"](Y4 * Y4 + RmT * RmT + A4 * A4);
    return S6["Math"]["floor"](SKT);
};

var M6T = function (YpT) {
    var ck = S6["Math"]["floor"](S6["Math"]["random"]() * 100000 + 10000);
    var cmT = S6["String"](YpT * ck);
    var pmT = 0;
    var zTT = [];
    var vJT = cmT["length"] >= 18 ? true : false;
    while (zTT["length"] < 6) {
        zTT["push"](S6["parseInt"](cmT["slice"](pmT, pmT + 2), 10));
        pmT = vJT ? pmT + 3 : pmT + 2;
    }
    var lCT = SWT(zTT);
    return [ck, lCT];
};


继续找dd2,简单还原下

parseInt(parseInt(S6.window.bmak.startTs / 23, 10) / (2016 * 2016), 10)


3、dvc里面的vmp参数分析

首先是插桩点:

1、while里面的epcode。

2、get和set方法。

3、String.fromCharCode方法。

4、this中变量的赋值、push操作。

5、算术运算(加减乘除求余)、位运算(与或非异或左移右移)位置。

打印好日志保存到本地分析,从后往前看。

最终结果是"acigcf9aYkakYf" + "acsw1v"得到,先分析"acigcf9aYkakYf"。


"acigcf9aYkakYf"的生成:每一个字符的添加都是["a","c","d","9","f","h","i","k","l","7","p","q","s","1","v","w","x","y","B","2"]数组的索引值,索引值又与那个疑似时间戳的里面得到。整体逻辑就是,遍历"01761530890985",取值作为索引去获取数组中的值。


"acsw1v"的生成,往上找一下’v',可以看到v来源于这个22数组。


往上找17,看到17 = 2366799 % 22。继续搜索2366799,我这里少打了减法的运算日志,但是可以看出2366799 = 2366910 - 111, 2366910 = 3315 * 714。其中减法运算的结果是要加绝对值Math.abs的。


向上找3315,可以看到3315 = 3264 | 51,3264 = 102 << 5,51 = 102 >> 1。


102 = "f".charCodeAt(),22数组对应索引5就是f,刚好v值的生成就是第6个。102 >> 1的1来源11010101000010110110011011011001的索引5,102 << 5里面的5是固定的。

向上找714,714 = 816 - 102, 816 = 102 << 3,3 = 3*1。 其中的102、1和前面一样。


搜索11010101000010110110011011011001的生成位置,从这个日志可以看出这是通过Number转的二进制字符串,使用toString(2)。


继续找3574294233,发现3574294233 = 181556985 + 3392737248,3392737248 = -902230048 >>> 0, 181556985 = 181556985 >>> 0。


分析-902230048和181556985的生成。整理下生成逻辑,发现是循环"01761530890982) Chrome/141.0.0.0 Safari/537.360",charCodeAt转十进制整数,上一次结果和固定数值33相乘,再和前面转码结果进行异或运算,-902230048和181556985生成都是一个逻辑。

大致流程基本上都走完了,还有一个22数组的生成,是根据固定数值"a3cd9efghiYjklm7opqrs1uvwQxyBz2"和前面的二进制字符串生成的。


4、vmp流程小结

  1. 初始数值:浏览器的ua、"a3cd9efghiYjklm7opqrs1uvwQxyBz2"、时间戳。传入参数分别对应delt、ajr、请求轮次、tovl。
  2. 预处理:算法会先把收集到的信息做两步处理,目的是把字符串类的信息转化为数值,方便后续运算:
    1. 将 “浏览器标识 + 时间戳 + 部分自定义参数”、“时间间隔 + 业务标识 + 固定 0” 这两组拼接后的字符串,分别通过一套哈希规则(类似给字符串算一个唯一数字)生成两个核心数值;
    2. 把这两个数值相加后转成二进制,同时单独把第一组的哈希值也转成二进制,得到两个二进制字符串(相当于生成了两组 “数字密钥”)。
  3. 筛选 “字符池”:用第二步生成的二进制字符串作为筛选规则,从预设的固定字符串里挑出一部分字符,组成一个 “可用字符池”:
    1. 规则很简单,要么字符位置的二进制位是 1,要么位置是 3 的倍数,满足其一就入选;
    2. 这个字符池是后续生成最终字符串的唯一来源。
  4. 生成最终字符串(分两段拼接):基于筛选好的字符池,用两种不同规则生成两段字符串,最后拼在一起就是最终结果:
    1. 第一段(简单规则):把 “自定义参数 + 加 3 后的时间戳” 拼接成字符串,每个字符直接当索引,从字符池里取对应位置的字符,拼起来;
    2. 第二段(复杂规则):取字符池前 6 个字符,每个字符先转成编码值,再做一系列位运算、算术运算(移位、乘减、取绝对值等),运算结果取余后再当索引,从字符池里重新取字符,拼成 6 位字符串;
    3. 最终结果 = 第一段字符串 + 第二段字符串。



传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回