概要

提示:仅供学习,不得用做商业交易,如有侵权请及时联系

逆向:JS逆向 - 盼之(decode__1174、sign)

URL:aHR0cHM6Ly93d3cucHpkcy5jb20vZ29vZHNMaXN0LzgvNg==

整体架构流程

提示:过debugger ---- 魔改浏览器

点击下一页发送POST请求

在这里插入图片描述

魔改浏览器网上自己找下,或者私我!!!

技术名词解释

提示:观察需要加密的参数-分析加密位置

1、请求载荷:

在这里插入图片描述

2、请求头:

在这里插入图片描述

3、分析请求头加密位置:全局搜索

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

const CryptoJS = require('crypto-js');
function get_header(o) {
    I = Date.now();
    for (a = I,
        "",
        s = "",
        f = new Array(1,2,3,4,5,6,7,8,9),
        l = 0; l < 6; l++)
            d = Math.floor(9 * Math.random()),
            s += f[d];
    if (c = Number(s), p = [], 'post')
        p.push("PZTimestamp=" + a + "&Random=" + c + "&2147483647=" + encodeURIComponent(JSON.stringify(o)))
    E = p.join("&") + "&accessKey=3qXyB7uf",O = void 0,O = E.replace(/[(]/g, "%28"),
    E = O = (O = (O = (O = (O = O.replace(/[)]/g, "%29")).replace(/[']/g, "%27")).replace(/[*]/g, "%2A")).replace(/[~]/g, "%7E")).replace(/[!!]/g, "%21"),
    b = CryptoJS.MD5(E).toString();
    return {
        Timestamp: a+'',
        strMd5: b,
        Random: c+''
    }
}

技术细节

提示:分析decode__1174的生成

1、堆栈断点,点击下一页触发断点:

在这里插入图片描述

2、观察参数是否生成:

在这里插入图片描述

3、往上跟一个栈,发现发送了一个send,那么可能是重写了xhr的send方法,然后通过一个对象去接收new URLSearchParams拿到href,去拼接的decode__1174

在这里插入图片描述

4、单步进去send方法,继续观察什么时候生成的

在这里插入图片描述

5、到这里我们可以看到,赋值了一个新对象,里面有H,猜测可能会对它进行拼接,继续往下跟栈

在这里插入图片描述

6、当我们一步一步跟栈下面,发现运行Ri这个函数,发现页面刷新了,xhr的值也拼接了,那么decode__1174肯定是这个函数生成的,进入Ri函数分析

在这里插入图片描述

7、刚进入就判断了window下面有没有该属性:_waf_bd8ce2ce37

在这里插入图片描述

其实这个值就是当我第一次请求,或者请求失败时返回的HTML里面的script

在这里插入图片描述

8、继续往下走,会发现去判断了xhr里面是否存在某些属性:

在这里插入图片描述
提示:补环境时,XMLHttpRequest的prototype一定得加上_waf_hook

9、当我们运行完R[ZC(M5.d)](XY, Xg[0x17 * -0x151 + -0x12af + 0x2d12 + ME], Xi[ZC(M5.n)], Xg[-0x1955 + 0x268f + -0xd3a], 0x1 * -0x12eb + -0x43 * -0x2f + 0x3 * 0x235),Xj里面就拼接了decode__1174

在这里插入图片描述

10、到这里我们可以知道,decode_1174肯定时XY函数生成,跟进去,里面一大堆的switch,这里我就不一步一步讲了,直接说位置

在这里插入图片描述

11、到这里你会发现值生成了,'28178cb220-'的值是固定的,那么最后只需要还原R[ZJ(M4.X6)](J, Xb)是怎么来的就行了

12、Xb是加密的明文,首页得知道它怎么来的,往上跟就是case 3的时候生成的

在这里插入图片描述

明文:[R[ZJ(M4.v)](XX, Xb), R[ZJ(M4.F)](XX, XQ), R[ZJ(M4.p)](X0), R[ZJ(M4.e)](new M['E'][(ZJ(M4.k))]()[ZJ(M4.G)](), ''), XV[ZJ(M4.J) + ZJ(M4.d)], XV[ZJ(M4.n) + ZJ(M4.S)], R[ZJ(M4.c)](f)]
  1. R[ZJ(M4.v)](XX, Xb):Xb ---- Xm、Xh进行md5再通过计算拼接得到,而Xm、Xh是通过_waf_bd8ce2ce37、请求方式、api、data…拼接的encodeURIComponent
    在这里插入图片描述

在这里插入图片描述
提示:坑点,Math.random重写了一份固定值,计算时用的其实是固定值

// 固定0.6398672226746067
func_chufa = function (a,b) {
    return a / b;
}
func_yushu = function (a,b) {
    return a % b;
}
func_jiafa = function (a,b) {
    return a + b;
}
func_chengfa = function (a,b) {
    return a * b;
}
function set_random(Xi) {
    var XM = {};
    XM["qTmGq"] = "function random() { [native code] }";
    var Xg = XM;
    F = -0x139d5b97 + -0xed0f55d + 0x5fd2a01a;
    // Error检测
    var XR = 1436544;
    var Xy = -0x17603115 + -0xf38cfa0f + -0x6e99ab * -0x412 + 997
        , XA = function () {
            return func_chufa(F = func_yushu(func_jiafa(func_chengfa(XR, F), Xi), Xy), Xy);
        };
    return XA['toString'] = function () {
        return Xg["qTmGq"];
    }, XA;
}
Math.random_ = Math.random;
Math.random = set_random(1693719615);
  1. RZJ(M4.p):这个值,确实是Math.random没重写之前的方法进行操作一个数组,然后操作0和1得到的一个数,直接扣就行
  2. RZJ(M4.p), R[ZJ(M4.e)](new M[‘E’](ZJ(M4.k))ZJ(M4.G), ‘’):时间戳 + ‘’
  3. XV[ZJ(M4.J) + ZJ(M4.d)]:window._waf_bd8ce2ce37
  4. XV[ZJ(M4.n) + ZJ(M4.S)]:window._waf_a86dfdc5f2 (当前js执行过程中生成的时间戳)
  5. RZJ(M4.c):固定值 2105840676a198dee460b7
  6. 最后通过join拼接的 “|”
    在这里插入图片描述

13、这里直接给出最后加密的函数:

var jiam = function (XM) {
        var Xg = 6;
        var x = ['T', 'J', 'P', 'g', 'l', 'M', '7', 'H', 'i', '8', 'k', '1', '0', 'h', 'O', 't', '3', 'Z', 'X', '2', '4', 'n', 'B', 'b', 'S', 'j', 'q', 'w', 'r', 'm', 'C', 'N', '6', 'p', 'I', 'E', 'e', 'u', 'x', 'Q', 'y', 'f', '/', '5', '_', '=', 'K', 'o', 'U', 'd', 'Y', 's', 'v', 'D', 'z', 'a', 'c', 'W', 'G', 'R', 'V', 'L', '9', 'A', 'F'];
        var Xy = function (XM) {
            return x[XM];
        };
        var XA, Xh, Xm, XV = {}, Xb = {}, XQ = '', Xw = '', XI = '', Xz = 2, Xf = 3, Xx = 2, XH = [], Xv = 0, XF = 0;
        for (Xm = 0; Xm < XM['length']; Xm += 1)
            if (XQ = XM["charAt"](Xm),
            Object['prototype']['hasOwnProperty']['call'](XV, XQ) || (XV[XQ] = Xf,
            Xf += 1,
            Xb[XQ] = !(0)),
            Xw = XI + XQ,
            Object['prototype']['hasOwnProperty']['call'](XV, Xw))
                XI = Xw;
            else {
                if (Object['prototype']['hasOwnProperty']['call'](Xb, XI)) {
                    if (XI['charCodeAt'](0) < 256) {
                        for (XA = 0; XA < Xx; XA++)
                            Xv <<= 1,
                            (XF == (Xg - 1)) ? (XF = 0,
                            XH['push'](Xy(Xv)),
                            Xv = 0) : XF++;
                        for (Xh = XI['charCodeAt'](0),
                        XA = 0; XA < 8; XA++)
                            Xv = ((Xv << 1) | (1 & Xh)),
                            (XF == (Xg - 1)) ? (XF = 0,
                            XH['push'](Xy(Xv)),
                            Xv = 0) : XF++,
                            Xh >>= 1;
                    } else {
                        for (Xh = 1,
                        XA = 0; XA < Xx; XA++)
                            Xv = ((Xv << 1) | Xh),
                            (XF == (Xg - 1)) ? (XF = 0,
                            XH['push'](Xy(Xv)),
                            Xv = 0) : XF++,
                            Xh = 0;
                        for (Xh = XI['charCodeAt'](0),
                        XA = 0; XA < 16; XA++)
                            Xv = ((Xv << 1) | (1 & Xh)),
                            (XF == (Xg - 1)) ? (XF = 0,
                            XH['push'](Xy(Xv)),
                            Xv = 0) : XF++,
                            Xh >>= 1;
                    }
                    (0 == --Xz) && (Xz = Math['pow'](2, Xx),
                    Xx++),
                    delete Xb[XI];
                } else {
                    for (Xh = XV[XI],
                    XA = 0; XA < Xx; XA++)
                        Xv = ((Xv << 1) | (1 & Xh)),
                        (XF == (Xg - 1)) ? (XF = 0,
                        XH['push'](Xy(Xv)),
                        Xv = 0) : XF++,
                        Xh >>= 1;
                }
                (0 == --Xz) && (Xz = Math['pow'](2, Xx),
                Xx++),
                XV[Xw] = Xf,
                Xf += -0x17bb + -0xc7 * -0x1c + 0x1f8,
                XI = String(XQ);
            }
        if ('' !== XI) {
            if (Object['prototype']['hasOwnProperty']['call'](Xb, XI)) {
                if (XI['charCodeAt'](0) < 256) {
                    for (XA = 0; XA < Xx; XA++)
                        Xv <<= -0xc3 * -0x15 + 0x4a * 0x52 + -0x27b2 * 0x1,
                        (XF == (Xg - 1)) ? (XF = -0xa67 + 0x11fc * 0x1 + -0x1 * 0x795,
                        XH['push'](Xy(Xv)),
                        Xv = 0x1 * -0xb60 + -0x1f4f + 0x2aaf) : XF++;
                    for (Xh = XI['charCodeAt'](0),
                    XA = 0; XA < 8; XA++)
                        Xv = ((Xv << 1) | (1 & Xh)),
                        (XF == (Xg - 1)) ? (XF = 0,
                        XH['push'](Xy(Xv)),
                        Xv = 0) : XF++,
                        Xh >>= 1;
                } else {
                    for (Xh = -0x8ec + -0x13a1 + 0x1c8e,
                    XA = 0; XA < Xx; XA++)
                        Xv = ((Xv << 1) | Xh),
                        (XF == (Xg - 1)) ? (XF = 0,
                        XH['push'](Xy(Xv)),
                        Xv = -0x7 * -0xd9 + -0x232 * 0x5 + 0x1 * 0x50b) : XF++,
                        Xh = -0xe95 + 0x3ed + -0x2aa * -0x4;
                    for (Xh = XI['charCodeAt'](0),
                    XA = 0; XA < 16; XA++)
                        Xv = ((Xv << 1) | (1 & Xh)),
                        (XF == (Xg - 1)) ? (XF = 0x48a + -0x1738 + 0x12ae,
                        XH['push'](Xy(Xv)),
                        Xv = 0) : XF++,
                        Xh >>= 0x1e29 + 0x225e + 0xac1 * -0x6;
                }
                (0 == --Xz) && (Xz = Math['pow'](0x973 + 0xa * -0x368 + 0x1 * 0x189f, Xx),
                Xx++),
                delete Xb[XI];
            } else {
                for (Xh = XV[XI],
                XA = -0x18a4 * -0x1 + 0xb55 + -0x23f9; XA < Xx; XA++)
                    Xv = ((Xv << 1) | (1 & Xh)),
                    (XF == (Xg - 1)) ? (XF = -0x1d03 + -0xcfd + 0x2a0 * 0x10,
                    XH['push'](Xy(Xv)),
                    Xv = -0x98f + 0x1 * -0x106b + 0x19fa) : XF++,
                    Xh >>= 0x151 * 0x1d + 0x120e + -0x1c1d * 0x2;
            }
            (0 == --Xz) && (Xz = Math['pow'](0x1a4f + 0x29 * -0x40 + -0x100d, Xx),
            Xx++);
        }
        for (Xh = 0xb40 + -0x2252 + 0x1714,
        XA = -0x1bd * 0xd + -0x209a + 0x3733; XA < Xx; XA++)
            Xv = ((Xv << 1) | (1 & Xh)),
            (XF == (Xg - 1)) ? (XF = 0x1687 + -0x33 * -0x32 + -0x207d,
            XH['push'](Xy(Xv)),
            Xv = 0) : XF++,
            Xh >>= 1;
        for (; ; ) {
            if (Xv <<= 1,XF == (Xg - 1)) {
                XH['push'](Xy(Xv));
                break;
            }
            XF++;
        }
        return XH['join']('');
}

在这里插入图片描述

14、最后扣完纯算:也才200行

在这里插入图片描述

15、py调用

在这里插入图片描述

小结

提示:学习交流主页,星球持续更新中:(+星球主页+v)

更多推荐