目录

某乎x-zse-96加密算法分析与还原

某乎x-zse-96加密算法分析与还原

**【🏠作者主页】:

【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作!

【🌟作者推荐】:对爬虫领域以及JS逆向分析感兴趣的朋友可以关注

未来作者会持续更新所用到、学到、看到的技术知识!包括但不限于:各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章**

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

1. 写在前面

最近比较忙,有近一个月没更新文章了~在上次周末的时候刚好有一个小需求需对全网一些主流的平台做一个关键词扫描。其中某些平台的话以前的文章都有过分析,所以没有文章的就简单记录一下吧!


分析网站

aHR0cHM6Ly93d3cuemhpaHUuY29tL3NlYXJjaD90eXBlPWNvbnRlbnQmcT0=

2. 接口分析

搜索接口的话除了 x-zse-96 需要解决动态生成外,其他的几个可以不需要去管它,如下所示:

https://i-blog.csdnimg.cn/direct/dc8cef6c143048b39a472cd5e0357643.png

3. 加密分析

这里的话全局搜索及跟栈都可以找到加密参数生成的入口位置

https://i-blog.csdnimg.cn/direct/d2f03827b966407baae013f8f5a34f01.png

可以看到上面 tp 的话是一个拼接的长字符串,由四部分相加组成。请求头里面的 X-Zse-93 、请求的接口路径、 cookie 里面的 d_c0 字段值、最后一个的开头 3_2.0 特征很明显也是请求头内的 X-Zse-81 参数,如下所示:

https://i-blog.csdnimg.cn/direct/1f4c176375f04555985639eb314cda91.png

然后上面计算得到的 MD5 值再经过 tJ(ti).encrypt() 进行加密得到最终的 64 位密文参数值,如下所示:

https://i-blog.csdnimg.cn/direct/037cb40d161143afa129f64403778019.png

重点就是后续对 MD5 二次加密的过程,需要去还原出来!这里作者当时为了快速实现需求也是做了一套补环境的方案!如果是补环境的话,那就会简单很多。把 ed 方法拿出来,因为它是入口,再把那个涉及 vmp1514 模块下面的JS全部拿下来并导出

然后在 ***.filter(Boolean).join("+") 这里拼接的地方拿到拼接的参数做一个标准的 MD5 后再调用 ZP 丢进行, D 是二段加密的方法入口处, tt 就是上面做了 MD5 的值,如下所示:

https://i-blog.csdnimg.cn/direct/f63a6df081a547c7b911e2dd4143d42d.png

然后剩下来的就是挂一个 Poxy 开始对着来补环境了,如下所示:

https://i-blog.csdnimg.cn/direct/8d4358a7a8ab4514ab2900b73775bb2c.png

这里的话就不去细说补环境了,网上公开的内容也蛮多,开始来分析纯算法的加密过程,核心的二段加密在 1514 模块内是经过 VMP ,所以需要去分析这段JS源码具体的加密逻辑实现的流程,如下所示:

1514: function(__unused_webpack_module, exports, __webpack_require__) {
    "use strict";
    var _type_of = __webpack_require__(74185)
      , x = function(tt) {
        return C(tt) || s(tt) || t()
    }
      , C = function(tt) {
        if (Array.isArray(tt)) {
            for (var te = 0, tr = Array(tt.length); te < tt.length; te++)
                tr[te] = tt[te];
            return tr
        }
    }
      , s = function(tt) {
        if (Symbol.A in Object(tt) || "[object Arguments]" === Object.prototype.toString.call(tt))
            return Array.from(tt)
    }
      , t = function() {
        throw TypeError("Invalid attempt to spread non-iterable instance")
    }
      , i = function(tt, te, tr) {
        te[tr] = 255 & tt >>> 24,
        te[tr + 1] = 255 & tt >>> 16,
        te[tr + 2] = 255 & tt >>> 8,
        te[tr + 3] = 255 & tt
    }
      , B = function(tt, te) {
        return (255 & tt[te]) << 24 | (255 & tt[te + 1]) << 16 | (255 & tt[te + 2]) << 8 | 255 & tt[te + 3]
    }
      , Q = function(tt, te) {
        return (4294967295 & tt) << te | tt >>> 32 - te
    }
      , G = function(tt) {
        var te = [, , , , ]
          , tr = [, , , , ];
        i(tt, te, 0),
        tr[0] = h.zb[255 & te[0]],
        tr[1] = h.zb[255 & te[1]],
        tr[2] = h.zb[255 & te[2]],
        tr[3] = h.zb[255 & te[3]];
        var ti = B(tr, 0);
        return ti ^ Q(ti, 2) ^ Q(ti, 10) ^ Q(ti, 18) ^ Q(ti, 24)
    }
      , l = function() {
        this.C = [0, 0, 0, 0],
        this.s = 0,
        this.t = [],
        this.S = [],
        this.h = [],
        this.i = [],
        this.B = [],
        this.Q = !1,
        this.G = [],
        this.D = [],
        this.w = 1024,
        this.g = null,
        this.a = Date.now(),
        this.e = 0,
        this.T = 255,
        this.V = null,
        this.U = Date.now,
        this.M = Array(32)
    };
    function o(tt) {
        return (o = "function" == typeof Symbol && "symbol" == _type_of._(Symbol.A) ? function(tt) {
            return void 0 === tt ? "undefined" : _type_of._(tt)
        }
        : function(tt) {
            return tt && "function" == typeof Symbol && tt.constructor === Symbol && tt !== Symbol.prototype ? "symbol" : void 0 === tt ? "undefined" : _type_of._(tt)
        }
        )(tt)
    }
    __webpack_unused_export__ = {
        value: !0
    };
    var __webpack_unused_export__, h, A = "3.0", S = "undefined" != typeof window ? window : {}, __g = {
        x: function(tt, te) {
            for (var tr = [], ti = tt.length, ta = 0; 0 < ti; ti -= 16) {
                for (var tu = tt.slice(16 * ta, 16 * (ta + 1)), tc = Array(16), tf = 0; tf < 16; tf++)
                    tc[tf] = tu[tf] ^ te[tf];
                te = __g.r(tc),
                tr = tr.concat(te),
                ta++
            }
            return tr
        },
        r: function(tt) {
            var te = Array(16)
              , tr = Array(36);
            tr[0] = B(tt, 0),
            tr[1] = B(tt, 4),
            tr[2] = B(tt, 8),
            tr[3] = B(tt, 12);
            for (var ti = 0; ti < 32; ti++) {
                var ta = G(tr[ti + 1] ^ tr[ti + 2] ^ tr[ti + 3] ^ h.zk[ti]);
                tr[ti + 4] = tr[ti] ^ ta
            }
            return i(tr[35], te, 0),
            i(tr[34], te, 4),
            i(tr[33], te, 8),
            i(tr[32], te, 12),
            te
        }
    };
    l.prototype.O = function(A, C, s) {
        for (var t, S, h, i, B, Q, G, D, w, g, a, e, E, T, r, V, U, M, O, c, I; this.T < this.w; )
            try {
                switch (this.T) {
                case 27:
                    this.C[this.c] = this.C[this.I] >> this.C[this.F],
                    this.M[12] = 35,
                    this.T = this.T * (this.C.length + (this.M[13] ? 3 : 9)) + 1;
                    break;
                case 34:
                    this.C[this.c] = this.C[this.I] & this.C[this.F],
                    this.T = this.T * (this.M[15] - 6) + 12;
                    break;
                case 41:
                    this.C[this.c] = this.C[this.I] <= this.C[this.F],
                    this.T = 8 * this.T + 27;
                    break;
                case 48:
                    this.C[this.c] = !this.C[this.I],
                    this.T = 7 * this.T + 16;
                    break;
                case 50:
                    this.C[this.c] = this.C[this.I] | this.C[this.F],
                    this.T = 6 * this.T + 52;
                    break;
                case 57:
                    this.C[this.c] = this.C[this.I] >>> this.C[this.F],
                    this.T = 7 * this.T - 47;
                    break;
                case 64:
                    this.C[this.c] = this.C[this.I] << this.C[this.F],
                    this.T = 5 * this.T + 32;
                    break;
                case 71:
                    this.C[this.c] = this.C[this.I] ^ this.C[this.F],
                    this.T = 6 * this.T - 74;
                    break;
                case 78:
                    this.C[this.c] = this.C[this.I] & this.C[this.F],
                    this.T = 4 * this.T + 40;
                    break;
                case 80:
                    this.C[this.c] = this.C[this.I] < this.C[this.F],
                    this.T = 5 * this.T - 48;
                    break;
                case 87:
                    this.C[this.c] = -this.C[this.I],
                    this.T = 3 * this.T + 91;
                    break;
                case 94:
                    this.C[this.c] = this.C[this.I] > this.C[this.F],
                    this.T = 4 * this.T - 24;
                    break;
                case 101:
                    this.C[this.c] = this.C[this.I]in this.C[this.F],
                    this.T = 3 * this.T + 49;
                    break;
                case 108:
                    this.C[this.c] = o(this.C[this.I]),
                    this.T = 2 * this.T + 136;
                    break;
                case 110:
                    this.C[this.c] = this.C[this.I] !== this.C[this.F],
                    this.T += 242;
                    break;
                case 117:
                    this.C[this.c] = this.C[this.I] && this.C[this.F],
                    this.T = 3 * this.T + 1;
                    break;
                case 124:
                    this.C[this.c] = this.C[this.I] || this.C[this.F],
                    this.T += 228;
                    break;
                case 131:
                    this.C[this.c] = this.C[this.I] >= this.C[this.F],
                    this.T = 3 * this.T - 41;
                    break;
                case 138:
                    this.C[this.c] = this.C[this.I] == this.C[this.F],
                    this.T = 2 * this.T + 76;
                    break;
                case 140:
                    this.C[this.c] = this.C[this.I] % this.C[this.F],
                    this.T += 212;
                    break;
                case 147:
                    this.C[this.c] = this.C[this.I] / this.C[this.F],
                    this.T += 205;
                    break;
                case 154:
                    this.C[this.c] = this.C[this.I] * this.C[this.F],
                    this.T += 198;
                    break;
                case 161:
                    this.C[this.c] = this.C[this.I] - this.C[this.F],
                    this.T += 191;
                    break;
                case 168:
                    this.C[this.c] = this.C[this.I] + this.C[this.F],
                    this.T = 2 * this.T + 16;
                    break;
                case 254:
                    this.C[this.c] = eval(i),
                    this.T += 20 < this.M[11] ? 98 : 89;
                    break;
                case 255:
                    this.s = C || 0,
                    this.M[26] = 52,
                    this.T += this.M[13] ? 8 : 6;
                    break;
                case 258:
                    g = {};
                    for (var F = 0; F < this.k; F++)
                        e = this.i.pop(),
                        a = this.i.pop(),
                        g[a] = e;
                    this.C[this.W] = g,
                    this.T += 94;
                    break;
                case 261:
                    this.D = s || [],
                    this.M[11] = 68,
                    this.T += this.M[26] ? 3 : 5;
                    break;
                case 264:
                    this.M[15] = 16,
                    this.T = "string" == typeof A ? 331 : 336;
                    break;
                case 266:
                    this.C[this.I][i] = this.i.pop(),
                    this.T += 86;
                    break;
                case 278:
                    this.C[this.c] = this.C[this.I][i],
                    this.T += this.M[22] ? 63 : 74;
                    break;
                case 283:
                    this.C[this.c] = eval(String.fromCharCode(this.C[this.I]));
                    break;
                case 300:
                    S = this.U(),
                    this.M[0] = 66,
                    this.T += this.M[11];
                    break;
                case 331:
                    D = atob(A),
                    w = D.charCodeAt(0) << 16 | D.charCodeAt(1) << 8 | D.charCodeAt(2);
                    for (var k = 3; k < w + 3; k += 3)
                        this.G.push(D.charCodeAt(k) << 16 | D.charCodeAt(k + 1) << 8 | D.charCodeAt(k + 2));
                    for (V = w + 3; V < D.length; )
                        E = D.charCodeAt(V) << 8 | D.charCodeAt(V + 1),
                        T = D.slice(V + 2, V + 2 + E),
                        this.D.push(T),
                        V += E + 2;
                    this.M[21] = 8,
                    this.T += 1e3 < V ? 21 : 35;
                    break;
                case 336:
                    this.G = A,
                    this.D = s,
                    this.M[18] = 134,
                    this.T += this.M[15];
                    break;
                case 344:
                    this.T = 3 * this.T - 8;
                    break;
                case 350:
                    U = 66,
                    M = [],
                    I = this.D[this.k];
                    for (var W = 0; W < I.length; W++)
                        M.push(String.fromCharCode(24 ^ I.charCodeAt(W) ^ U)),
                        U = 24 ^ I.charCodeAt(W) ^ U;
                    r = parseInt(M.join("").split("|")[1]),
                    this.C[this.W] = this.i.slice(this.i.length - r),
                    this.i = this.i.slice(0, this.i.length - r),
                    this.T += 2;
                    break;
                case 352:
                    this.e = this.G[this.s++],
                    this.T -= this.M[26];
                    break;
                case 360:
                    this.a = S,
                    this.T += this.M[0];
                    break;
                case 368:
                    this.T -= 500 < S - this.a ? 24 : 8;
                    break;
                case 380:
                    this.i.push(16383 & this.e),
                    this.T -= 28;
                    break;
                case 400:
                    this.i.push(this.S[16383 & this.e]),
                    this.T -= 48;
                    break;
                case 408:
                    this.T -= 64;
                    break;
                case 413:
                    this.C[this.e >> 15 & 7] = (this.e >> 18 & 1) == 0 ? 32767 & this.e : this.S[32767 & this.e],
                    this.T -= 61;
                    break;
                case 418:
                    this.S[65535 & this.e] = this.C[this.e >> 16 & 7],
                    this.T -= this.e >> 16 < 20 ? 66 : 80;
                    break;
                case 423:
                    this.c = this.e >> 16 & 7,
                    this.I = this.e >> 13 & 7,
                    this.F = this.e >> 10 & 7,
                    this.J = 1023 & this.e,
                    this.T -= 255 + 6 * this.J + this.J % 5;
                    break;
                case 426:
                    this.T += 5 * (this.e >> 19) - 18;
                    break;
                case 428:
                    this.W = this.e >> 16 & 7,
                    this.k = 65535 & this.e,
                    this.t.push(this.s),
                    this.h.push(this.S),
                    this.s = this.C[this.W],
                    this.S = [];
                    for (var J = 0; J < this.k; J++)
                        this.S.unshift(this.i.pop());
                    this.B.push(this.i),
                    this.i = [],
                    this.T -= 76;
                    break;
                case 433:
                    this.s = this.t.pop(),
                    this.S = this.h.pop(),
                    this.i = this.B.pop(),
                    this.T -= 81;
                    break;
                case 438:
                    this.Q = this.C[this.e >> 16 & 7],
                    this.T -= 86;
                    break;
                case 440:
                    U = 66,
                    M = [],
                    I = this.D[16383 & this.e];
                    for (var b = 0; b < I.length; b++)
                        M.push(String.fromCharCode(24 ^ I.charCodeAt(b) ^ U)),
                        U = 24 ^ I.charCodeAt(b) ^ U;
                    M = M.join("").split("|"),
                    O = parseInt(M.shift()),
                    this.i.push(0 === O ? M.join("|") : 1 === O ? -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()) : 2 === O ? eval(M.join()) : 3 === O ? null : void 0),
                    this.T -= 88;
                    break;
                case 443:
                    this.b = this.e >> 2 & 65535,
                    this.J = 3 & this.e,
                    0 === this.J ? this.s = this.b : 1 === this.J ? this.Q && (this.s = this.b) : 2 === this.J && this.Q || (this.s = this.b),
                    this.g = null,
                    this.T -= 91;
                    break;
                case 445:
                    this.i.push(this.C[this.e >> 14 & 7]),
                    this.T -= 93;
                    break;
                case 448:
                    this.W = this.e >> 16 & 7,
                    this.k = this.e >> 2 & 4095,
                    this.J = 3 & this.e,
                    Q = 1 === this.J && this.i.pop(),
                    G = this.i.slice(this.i.length - this.k, this.i.length),
                    this.i = this.i.slice(0, this.i.length - this.k),
                    c = 2 < G.length ? 3 : G.length,
                    this.T += 6 * this.J + 1 + 10 * c;
                    break;
                case 449:
                    this.C[3] = this.C[this.W](),
                    this.T -= 97 - G.length;
                    break;
                case 455:
                    this.C[3] = this.C[this.W][Q](),
                    this.T -= 103 + G.length;
                    break;
                case 453:
                    B = this.e >> 17 & 3,
                    this.T = 0 === B ? 445 : 1 === B ? 380 : 2 === B ? 400 : 440;
                    break;
                case 458:
                    this.J = this.e >> 17 & 3,
                    this.c = this.e >> 14 & 7,
                    this.I = this.e >> 11 & 7,
                    i = this.i.pop(),
                    this.T -= 12 * this.J + 180;
                    break;
                case 459:
                    this.C[3] = this.C[this.W](G[0]),
                    this.T -= 100 + 7 * G.length;
                    break;
                case 461:
                    this.C[3] = new this.C[this.W],
                    this.T -= 109 - G.length;
                    break;
                case 463:
                    U = 66,
                    M = [],
                    I = this.D[65535 & this.e];
                    for (var n = 0; n < I.length; n++)
                        M.push(String.fromCharCode(24 ^ I.charCodeAt(n) ^ U)),
                        U = 24 ^ I.charCodeAt(n) ^ U;
                    M = M.join("").split("|"),
                    O = parseInt(M.shift()),
                    this.T += 10 * O + 3;
                    break;
                case 465:
                    this.C[3] = this.C[this.W][Q](G[0]),
                    this.T -= 13 * G.length + 100;
                    break;
                case 466:
                    this.C[this.e >> 16 & 7] = M.join("|"),
                    this.T -= 114 * M.length;
                    break;
                case 468:
                    this.g = 65535 & this.e,
                    this.T -= 116;
                    break;
                case 469:
                    this.C[3] = this.C[this.W](G[0], G[1]),
                    this.T -= 119 - G.length;
                    break;
                case 471:
                    this.C[3] = new this.C[this.W](G[0]),
                    this.T -= 118 + G.length;
                    break;
                case 473:
                    throw this.C[this.e >> 16 & 7];
                case 475:
                    this.C[3] = this.C[this.W][Q](G[0], G[1]),
                    this.T -= 123;
                    break;
                case 476:
                    this.C[this.e >> 16 & 7] = -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()),
                    this.T -= this.M[21] < 10 ? 124 : 126;
                    break;
                case 478:
                    t = [0].concat(x(this.S)),
                    this.V = 65535 & this.e,
                    h = this,
                    this.C[3] = function(tt) {
                        var te = new l;
                        return te.S = t,
                        te.S[0] = tt,
                        te.O(h.G, h.V, h.D),
                        te.C[3]
                    }
                    ,
                    this.T -= 50 < this.M[3] ? 120 : 126;
                    break;
                case 479:
                    this.C[3] = this.C[this.W].apply(null, G),
                    this.M[3] = 168,
                    this.T -= this.M[9] ? 127 : 128;
                    break;
                case 481:
                    this.C[3] = new this.C[this.W](G[0],G[1]),
                    this.T -= 10 * G.length + 109;
                    break;
                case 483:
                    this.J = this.e >> 15 & 15,
                    this.W = this.e >> 12 & 7,
                    this.k = 4095 & this.e,
                    this.T = 0 === this.J ? 258 : 350;
                    break;
                case 485:
                    this.C[3] = this.C[this.W][Q].apply(null, G),
                    this.T -= this.M[15] % 2 == 1 ? 143 : 133;
                    break;
                case 486:
                    this.C[this.e >> 16 & 7] = eval(M.join()),
                    this.T -= this.M[18];
                    break;
                case 491:
                    this.C[3] = new this.C[this.W].apply(null,G),
                    this.T -= this.M[8] / this.M[1] < 10 ? 139 : 130;
                    break;
                case 496:
                    this.C[this.e >> 16 & 7] = null,
                    this.T -= 10 < this.M[5] - this.M[3] ? 160 : 144;
                    break;
                case 506:
                    this.C[this.e >> 16 & 7] = void 0,
                    this.T -= this.M[18] % this.M[12] == 1 ? 154 : 145;
                    break;
                default:
                    this.T = this.w
                }
            } catch (A) {
                this.g && (this.s = this.g),
                this.T -= 114
            }
    }
    ,
    "undefined" != typeof window && (S.__ZH__ = S.__ZH__ || {},
    h = S.__ZH__.zse = S.__ZH__.zse || {},
    (new l).O("ABt7CAAUSAAACADfSAAACAD1SAAACAAHSAAACAD4SAAACAACSAAACADCSAAACADRSAAACABXSAAACAAGSAAACADjSAAACAD9SAAACADwSAAACACASAAACADeSAAACABbSAAACADtSAAACAAJSAAACAB9SAAACACdSAAACADmSAAACABdSAAACAD8SAAACADNSAAACABaSAAACABPSAAACACQSAAACADHSAAACACfSAAACADFSAAACAC6SAAACACnSAAACAAnSAAACAAlSAAACACcSAAACADGSAAACAAmSAAACAAqSAAACAArSAAACACoSAAACADZSAAACACZSAAACAAPSAAACABnSAAACABQSAAACAC9SAAACABHSAAACAC/SAAACABhSAAACABUSAAACAD3SAAACABfSAAACAAkSAAACABFSAAACAAOSAAACAAjSAAACAAMSAAACACrSAAACAAcSAAACABySAAACACySAAACACUSAAACABWSAAACAC2SAAACAAgSAAACABTSAAACACeSAAACABtSAAACAAWSAAACAD/SAAACABeSAAACADuSAAACACXSAAACABVSAAACABNSAAACAB8SAAACAD+SAAACAASSAAACAAESAAACAAaSAAACAB7SAAACACwSAAACADoSAAACADBSAAACACDSAAACACsSAAACACPSAAACACOSAAACACWSAAACAAeSAAACAAKSAAACACSSAAACACiSAAACAA+SAAACADgSAAACADaSAAACADESAAACADlSAAACAABSAAACADASAAACADVSAAACAAbSAAACABuSAAACAA4SAAACADnSAAACAC0SAAACACKSAAACABrSAAACADySAAACAC7SAAACAA2SAAACAB4SAAACAATSAAACAAsSAAACAB1SAAACADkSAAACADXSAAACADLSAAACAA1SAAACADvSAAACAD7SAAACAB/SAAACABRSAAACAALSAAACACFSAAACABgSAAACADMSAAACACESAAACAApSAAACABzSAAACABJSAAACAA3SAAACAD5SAAACACTSAAACABmSAAACAAwSAAACAB6SAAACACRSAAACABqSAAACAB2SAAACABKSAAACAC+SAAACAAdSAAACAAQSAAACACuSAAACAAFSAAACACxSAAACACBSAAACAA/SAAACABxSAAACABjSAAACAAfSAAACAChSAAACABMSAAACAD2SAAACAAiSAAACADTSAAACAANSAAACAA8SAAACABESAAACADPSAAACACgSAAACABBSAAACABvSAAACABSSAAACAClSAAACABDSAAACACpSAAACADhSAAACAA5SAAACABwSAAACAD0SAAACACbSAAACAAzSAAACADsSAAACADISAAACADpSAAACAA6SAAACAA9SAAACAAvSAAACABkSAAACACJSAAACAC5SAAACABASAAACAARSAAACABGSAAACADqSAAACACjSAAACADbSAAACABsSAAACACqSAAACACmSAAACAA7SAAACACVSAAACAA0SAAACABpSAAACAAYSAAACADUSAAACABOSAAACACtSAAACAAtSAAACAAASAAACAB0SAAACADiSAAACAB3SAAACACISAAACADOSAAACACHSAAACACvSAAACADDSAAACAAZSAAACABcSAAACAB5SAAACADQSAAACAB+SAAACACLSAAACAADSAAACABLSAAACACNSAAACAAVSAAACACCSAAACABiSAAACADxSAAACAAoSAAACACaSAAACABCSAAACAC4SAAACAAxSAAACAC1SAAACAAuSAAACADzSAAACABYSAAACABlSAAACAC3SAAACAAISAAACAAXSAAACABISAAACAC8SAAACABoSAAACACzSAAACADSSAAACACGSAAACAD6SAAACADJSAAACACkSAAACABZSAAACADYSAAACADKSAAACADcSAAACAAySAAACADdSAAACACYSAAACACMSAAACAAhSAAACADrSAAACADWSAAAeIAAEAAACAB4SAAACAAySAAACABiSAAACABlSAAACABjSAAACABiSAAACAB3SAAACABkSAAACABnSAAACABrSAAACABjSAAACAB3SAAACABhSAAACABjSAAACABuSAAACABvSAAAeIABEAABCABkSAAACAAzSAAACABkSAAACAAySAAACABlSAAACAA3SAAACAAySAAACAA2SAAACABmSAAACAA1SAAACAAwSAAACABkSAAACAA0SAAACAAxSAAACAAwSAAACAAxSAAAeIABEAACCAAgSAAATgACVAAAQAAGEwADDAADSAAADAACSAAADAAASAAACANcIAADDAADSAAASAAATgADVAAATgAEUAAATgAFUAAATgAGUgAADAAASAAASAAATgADVAAATgAEUAAATgAFUAAATgAHUgAADAABSAAASAAATgADVAAATgAEUAAATgAFUAAATgAIUgAAcAgUSMAATgAJVAAATgAKUgAAAAAADAABSAAADAAAUAAACID/GwQPCAAYG2AREwAGDAABCIABGwQASMAADAAAUAAACID/GwQPCAAQG2AREwAHDAABCIACGwQASMAADAAAUAAACID/GwQPCAAIG2AREwAIDAABCIADGwQASMAADAAAUAAACID/GwQPEwAJDYAGDAAHG2ATDAAIG2ATDAAJG2ATKAAACAD/DIAACQAYGygSGwwPSMAASMAADAACSAAADAABUgAACAD/DIAACQAQGygSGwwPSMAASMAADAACCIABGwQASMAADAABUgAACAD/DIAACQAIGygSGwwPSMAASMAADAACCIACGwQASMAADAABUgAACAD/DIAAGwQPSMAASMAADAACCIADGwQASMAADAABUgAAKAAACAAgDIABGwQBEwANDAAAWQALGwQPDAABG2AREwAODAAODIAADQANGygSGwwTEwAPDYAPKAAACAAESAAATgACVAAAQAAGEwAQCAAESAAATgACVAAAQAAGEwAFDAAASAAADAAQSAAACAAASAAACAKsIAADCAAASAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAAASAAADAAFUgAACAABSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAABSAAADAAFUgAACAACSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAACSAAADAAFUgAACAADSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAADSAAADAAFUgAADAAFSAAACAAASAAACAJ8IAACEwARDAARSAAACAANSAAACALdIAACEwASDAARSAAACAAXSAAACALdIAACEwATDAARDIASGwQQDAATG2AQEwAUDYAUKAAAWAAMSAAAWAANSAAAWAAOSAAAWAAPSAAAWAAQSAAAWAARSAAAWAASSAAAWAATSAAAWAAUSAAAWAAVSAAAWAAWSAAAWAAXSAAAWAAYSAAAWAAZSAAAWAAaSAAAWAAbSAAAWAAcSAAAWAAdSAAAWAAeSAAAWAAfSAAAWAAgSAAAWAAhSAAAWAAiSAAAWAAjSAAAWAAkSAAAWAAlSAAAWAAmSAAAWAAnSAAAWAAoSAAAWAApSAAAWAAqSAAAWAArSAAAeIAsEAAXWAAtSAAAWAAuSAAAWAAvSAAAWAAwSAAAeIAxEAAYCAAESAAATgACVAAAQAAGEwAZCAAkSAAATgACVAAAQAAGEwAaDAABSAAACAAASAAACAJ8IAACSMAASMAACAAASAAADAAZUgAADAABSAAACAAESAAACAJ8IAACSMAASMAACAABSAAADAAZUgAADAABSAAACAAISAAACAJ8IAACSMAASMAACAACSAAADAAZUgAADAABSAAACAAMSAAACAJ8IAACSMAASMAACAADSAAADAAZUgAACAAASAAADAAZUAAACIAASEAADIAYUEgAGwQQSMAASMAACAAASAAADAAaUgAACAABSAAADAAZUAAACIABSEAADIAYUEgAGwQQSMAASMAACAABSAAADAAaUgAACAACSAAADAAZUAAACIACSEAADIAYUEgAGwQQSMAASMAACAACSAAADAAaUgAACAADSAAADAAZUAAACIADSEAADIAYUEgAGwQQSMAASMAACAADSAAADAAaUgAACAAAEAAJDAAJCIAgGwQOMwAGOBG2DAAJCIABGwQASMAADAAaUAAAEAAbDAAJCIACGwQASMAADAAaUAAAEAAcDAAJCIADGwQASMAADAAaUAAAEAAdDAAbDIAcGwQQDAAdG2AQDAAJSAAADAAXUAAAG2AQEwAeDAAeSAAADAACSAAACALvIAACEwAfDAAJSAAADAAaUAAADIAfGwQQSMAASMAADAAJCIAEGwQASMAADAAaUgAADAAJCIAEGwQASMAADAAaUAAASAAASAAADAAJSAAADAAAUgAADAAJCIABGQQAEQAJOBCIKAAADAABTgAyUAAACIAQGwQEEwAVCAAQDIAVGwQBEwAKCAAAEAAhDAAhDIAKGwQOMwAGOBImDAAKSAAADAABTgAzQAAFDAAhCIABGQQAEQAhOBHoCAAASAAACAAQSAAADAABTgA0QAAJEwAiCAAQSAAATgACVAAAQAAGEwAjCAAAEAALDAALCIAQGwQOMwAGOBLSDAALSAAADAAiUAAADIALSEAADIAAUEgAGwQQCAAqG2AQSMAASMAADAALSAAADAAjUgAA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"));
    var D = function(tt) {
        return __g._encrypt(encodeURIComponent(tt))
    };
    exports.XL = A,
    exports.ZP = D
},

开始之前可以先静态去分析一下上面的这段JS,先是一个 switch 然后通过 this.T 的值来决定执行啥操作!它相当于一个状态的 变量 ,不同的 case 分支来对应不同的操作, VMP 常见的一个实现方式

然后往下翻翻,一堆 位运算 以此来增加代码的 复杂性混淆度 。代码里面的那个 eval 的函数,也是常见的一个特征之一!来动态执行一些 JS 代码,增强隐蔽性,如下所示:

https://i-blog.csdnimg.cn/direct/ad859b07ef8444099fac134aaf6cb54c.png

开始对 case 的分支中关键操作位置插桩日志( 如赋值、函数调用、位运算 )以及相关变量的值。

开始分析日志,首先看不到第一步 MD5 计算出来的结果进行一个 charCodeAt 操作转换为 32 位的一个数组。实现如下所示:

md5_value = 'MD5的值'
array_32 = [ord(i) for i in md5_value]

https://i-blog.csdnimg.cn/direct/329f8cd4780e478e86946ba9b9be1e1b.png

然后第二步在 32 位的数组基础上再次往首插入两个数值, 0 是可以直接固定的,另一个 107 是随机数取整得到的,如下所示:

https://i-blog.csdnimg.cn/direct/0906d726af3046ca8b5b4227ef248022.png

之后第三步的时候它这个 MD5 的数组最终会填充到 48 位,从上面首位插两位数值以后就是往末位继续插值,不断的往末端追加 14 ,直到满足 48 位数组为止,如下所示:

https://i-blog.csdnimg.cn/direct/d314baec8cf7495f9616ff81fc98832d.png

接着第四步继续往下上面得到一个头尾填充后的 48 位数组以后,再次通过分片的方式对 48 位数组取 [:16] 的方式得到一个新的 16 位数组,如下所示:

https://i-blog.csdnimg.cn/direct/724d6837d3d44c1891494760068dbb3c.png

至此,来到了第五步!上面截止到当前已经有了三个 数组 。继续往下还是一些数组的操作。这种时候边分析边记录一些关键点很有必要,不然梳理起来有点容易丢失上下文~

先将上面 分片 得到的 16 位数组作为参数传递到某个自定义的函数内,这个函数主要实现的就是对这个 16 位数进行加密处理的,函数内一个固定的长度为 16 的数组,作为偏移量用于后续的按位异或操作生成 16 数组,如下所示:

https://i-blog.csdnimg.cn/direct/31b6faa4403049e7bbb19db070118863.png

它那个调用的函数是它自己内部自定义的函数,代码如下所示:

https://i-blog.csdnimg.cn/direct/f5da42aeb9044cab899fa945533044ca.png

16 位第一轮数组将经过上面的算法进行运算。过程则是将输入的 16 位字节数组拆分成 432 位整数并存储到临时数组的前 4 个位置!然后进行 32 次循环,每次循环进行一系列的变换操作,然后需要注意一下的就是在循环的过程中 h.zk 是一个预先定义好的常量数组!将从里面索引元素进行按位异或操作!对照上面的日志JS还原大致就是下面这样子的:

ENCRYPT_CONSTANTS = {
    "zk": [], # 自行获取
    "zb": []  # 自行获取
}
def split_int_to_bytes(int_value, byte_array, start_index):
    byte_array[start_index] = (int_value >> 24) & 255
    byte_array[start_index + 1] = (int_value >> 16) & 255
    byte_array[start_index + 2] = (int_value >> 8) & 255
    byte_array[start_index + 3] = int_value & 255
    return byte_array


def circular_left_shift(int_value, shift_amount):
    int_value = int_value & 0xFFFFFFFF
    return ((int_value << shift_amount) | (int_value >> (32 - shift_amount))) & 0xFFFFFFFF


def combine_bytes_to_int(byte_array, start_index):
    return ((byte_array[start_index] & 255) << 24) | ((byte_array[start_index + 1] & 255) << 16) | ((byte_array[start_index + 2] & 255) << 8) | (byte_array[start_index + 3] & 255)


def transform_32bit_int(int_value):
    byte_array_1 = [0] * 4
    byte_array_2 = [0] * 4
    byte_array_1 = split_int_to_bytes(int_value, byte_array_1, 0)
    byte_array_2[0] = ENCRYPT_CONSTANTS["zb"][byte_array_1[0] & 255]
    byte_array_2[1] = ENCRYPT_CONSTANTS["zb"][byte_array_1[1] & 255]
    byte_array_2[2] = ENCRYPT_CONSTANTS["zb"][byte_array_1[2] & 255]
    byte_array_2[3] = ENCRYPT_CONSTANTS["zb"][byte_array_1[3] & 255]
    combined_int = combine_bytes_to_int(byte_array_2, 0)
    return combined_int ^ circular_left_shift(combined_int, 2) ^ circular_left_shift(combined_int, 10) ^ circular_left_shift(combined_int, 18) ^ circular_left_shift(combined_int, 24)


def transform_16_byte_array(byte_array):
    result_array = [0] * 16
    temp_array = [0] * 36
    temp_array[0] = combine_bytes_to_int(byte_array, 0)
    temp_array[1] = combine_bytes_to_int(byte_array, 4)
    temp_array[2] = combine_bytes_to_int(byte_array, 8)
    temp_array[3] = combine_bytes_to_int(byte_array, 12)
    for i in range(32):
        transformed_value = transform_32bit_int(temp_array[i + 1] ^ temp_array[i + 2] ^ temp_array[i + 3] ^ ENCRYPT_CONSTANTS["zk"][i])
        temp_array[i + 4] = temp_array[i] ^ transformed_value
    result_array = split_int_to_bytes(temp_array[35], result_array, 0)
    result_array = split_int_to_bytes(temp_array[34], result_array, 4)
    result_array = split_int_to_bytes(temp_array[33], result_array, 8)
    result_array = split_int_to_bytes(temp_array[32], result_array, 12)
    return result_array

上面还原的 Py 代码中的 zk 32位数组与 zb 256位定义数组可以自行通过日志信息拿到贴进去就可以,如下所示:

https://i-blog.csdnimg.cn/direct/3747eb39766d48fc9d735be63fcc8b75.png

然后再来到第六步…第一次在上面对 48 位数组取了一个 [:16] 的分片数组,这里继续取 [16:48] 剩余的数组部分,如下所示:

https://i-blog.csdnimg.cn/direct/ce1cee394c9f40f8bfa9ad40002f4348.png

取了之后干什么?准备开始进行第七步!将上面第五步计算得到的新的 16 位数组跟第六步的分片 32 位数组进行运算。先是对 32 位数组进行分组处理,按照 16 字节一组来拆分出来。然后拆出来的每组跟传进来的那个 16 数组进行异或!完了丢给第五步的那个算法得到一个 32 位数组,最终 16+32 得到一个 48 数组,如下所示:

https://i-blog.csdnimg.cn/direct/56e95208d5fb42a7ba4aa7062749e7d3.png

最后第八步将上面得到的 48 位数组经过函数拆成 3 个一组进行编码处理, 三合一 为整数,然后将该整数按每 6 位一组进行拆分,得到一个长度 4 的数组,如下所示:

https://i-blog.csdnimg.cn/direct/f352a517d80041369e23380b7d955fad.png

综上分析,这里可以用 Py 进行算法操作的还原,代码实现如下:

def generate_initial_array(md5_hash):
    initial_array = [ord(c) for c in md5_hash]
    initial_array.insert(0, 0)
    initial_array.insert(0, random.randint(0, 126))
    while len(initial_array) < 48:
        initial_array.append(14)
    first_16_bytes = encrypt_16_byte_array(initial_array[:16])
    remaining_32_bytes = process_32_byte_array(initial_array[16:48], first_16_bytes)
    result_array = first_16_bytes + remaining_32_bytes
    return result_array

最终就是遍历新得到的数组!将其作为索引从下面的固定的字符集里面不断的取对应值,生成一个 64 位的密文结果,如下所示:

https://i-blog.csdnimg.cn/direct/19d98eddf15b49f6ac5d3da5b4b270f4.png

https://i-blog.csdnimg.cn/direct/36801179e8364e99b507e3f9d1066e14.png

4. 算法实现

最后,某些常量数组以及字符集自己照着复现的时候补全就行,还原后的加密算法如下所示:

import hashlib
import random

ENCODE_CHAR_SET = "" # 自行获取

# 自行获取
ENCRYPT_CONSTANTS = {
    "keys": [],
    "arr": []
}

def split_int_to_bytes(int_value, byte_array, start_index):
    byte_array[start_index] = (int_value >> 24) & 255
    byte_array[start_index + 1] = (int_value >> 16) & 255
    byte_array[start_index + 2] = (int_value >> 8) & 255
    byte_array[start_index + 3] = int_value & 255
    return byte_array


def circular_left_shift(int_value, shift_amount):
    int_value = int_value & 0xFFFFFFFF
    return ((int_value << shift_amount) | (int_value >> (32 - shift_amount))) & 0xFFFFFFFF


def combine_bytes_to_int(byte_array, start_index):
    return ((byte_array[start_index] & 255) << 24) | ((byte_array[start_index + 1] & 255) << 16) | ((byte_array[start_index + 2] & 255) << 8) | (byte_array[start_index + 3] & 255)


def transform_32bit_int(int_value):
    byte_array_1 = [0] * 4
    byte_array_2 = [0] * 4
    byte_array_1 = split_int_to_bytes(int_value, byte_array_1, 0)
    byte_array_2[0] = ENCRYPT_CONSTANTS["arr"][byte_array_1[0] & 255]
    byte_array_2[1] = ENCRYPT_CONSTANTS["arr"][byte_array_1[1] & 255]
    byte_array_2[2] = ENCRYPT_CONSTANTS["arr"][byte_array_1[2] & 255]
    byte_array_2[3] = ENCRYPT_CONSTANTS["arr"][byte_array_1[3] & 255]
    combined_int = combine_bytes_to_int(byte_array_2, 0)
    return combined_int ^ circular_left_shift(combined_int, 2) ^ circular_left_shift(combined_int, 10) ^ circular_left_shift(combined_int, 18) ^ circular_left_shift(combined_int, 24)


def transform_16_byte_array(byte_array):
    result_array = [0] * 16
    temp_array = [0] * 36
    temp_array[0] = combine_bytes_to_int(byte_array, 0)
    temp_array[1] = combine_bytes_to_int(byte_array, 4)
    temp_array[2] = combine_bytes_to_int(byte_array, 8)
    temp_array[3] = combine_bytes_to_int(byte_array, 12)
    for i in range(32):
        transformed_value = transform_32bit_int(temp_array[i + 1] ^ temp_array[i + 2] ^ temp_array[i + 3] ^ ENCRYPT_CONSTANTS["keys"][i])
        temp_array[i + 4] = temp_array[i] ^ transformed_value
    result_array = split_int_to_bytes(temp_array[35], result_array, 0)
    result_array = split_int_to_bytes(temp_array[34], result_array, 4)
    result_array = split_int_to_bytes(temp_array[33], result_array, 8)
    result_array = split_int_to_bytes(temp_array[32], result_array, 12)
    return result_array


def process_32_byte_array(byte_array, initial_array):
    result_array = []
    current_index = 0
    remaining_length = len(byte_array)
    while remaining_length > 0:
        sub_array = byte_array[16 * current_index:16 * (current_index + 1)]
        xor_array = [0] * 16
        for i in range(16):
            xor_array[i] = sub_array[i] ^ initial_array[i]
        initial_array = transform_16_byte_array(xor_array)
        result_array.extend(initial_array)
        current_index += 1
        remaining_length -= 16
    return result_array


def encrypt_16_byte_array(byte_array):
    result = []
    offset_array = [] # 16位数组自行获取
    for i in range(len(byte_array)):
        xor_value_1 = byte_array[i] ^ offset_array[i]
        xor_value_2 = xor_value_1 ^ 42
        result.append(xor_value_2)
    return transform_16_byte_array(result)


def encode_3_element_array(array):
    shifted_value_1 = array[1] << 8
    combined_value_1 = array[0] | shifted_value_1
    shifted_value_2 = array[2] << 16
    combined_value_2 = combined_value_1 | shifted_value_2
    result_array = []
    shift_amount = 6
    result_array.append(combined_value_2 & 63)
    while len(result_array) < 4:
        shifted_value = combined_value_2 >> shift_amount
        result_array.append(shifted_value & 63)
        shift_amount += 6
    return result_array


def generate_initial_array(md5_hash):
    """
    根据 MD5 哈希值生成初始化数组
    """
    initial_array = [ord(c) for c in md5_hash]
    initial_array.insert(0, 0)
    initial_array.insert(0, random.randint(0, 126))
    while len(initial_array) < 48:
        initial_array.append(14)
    first_16_bytes = encrypt_16_byte_array(initial_array[:16])
    remaining_32_bytes = process_32_byte_array(initial_array[16:48], first_16_bytes)
    result_array = first_16_bytes + remaining_32_bytes
    return result_array


def generate_zse_96_signature(md5_hash):
    """
    根据 MD5 哈希值生成zse签名
    """
    result_array = []
    initial_array = generate_initial_array(md5_hash)
    for i in range(47, -1, -4):
        initial_array[i] ^= 58
    initial_array.reverse()
    for j in range(3, len(initial_array) + 1, 3):
        sub_array = initial_array[j - 3:j]
        result_array.extend(encode_3_element_array(sub_array))
    signature = ""
    for index in result_array:
        signature += ENCODE_CHAR_SET[index]
    return signature

https://i-blog.csdnimg.cn/direct/b07156d782c64a52bfb66077fefae901.png

最后,将 Py 算法对接到搜索测试是通过的,验证结果如下所示:

https://i-blog.csdnimg.cn/direct/e765eadb859d46838e4236bf8f7ba1ac.png