JavaScript逆向:console.log插桩分析某网站登陆加密模块

发布于:2023-05-22 ⋅ 阅读:(187) ⋅ 点赞:(0)

声明:案例分析仅供学习交流使用,勿用于任何非法用途。如学习者进一步逆向并对版权方造成损失,请自行承担法律后果,本人概不负责。

要挖掘登陆模块,首先查看其登陆POST请求,其中password字段需要逆向,这里是随机输入的密码【321654】:
在这里插入图片描述
要找到password字段的生成方式,可以从接口入手,全局搜“/user/login”:
在这里插入图片描述
找到对应的js文件后,由于代码被压缩成一行了,点进去是无法直接达到目标位置,但可以格式化后搜索“/user/login”找到目标位置:
在这里插入图片描述
此处下断点调试,发现在发出请求时已经生成了加密后的password:
在这里插入图片描述
从调用栈往上跟,最终找到此处是明文->密文的地方:
在这里插入图片描述
跟进去发现最终是调用了 /chunks/cacd27eb40cd7e51ddd90f7c7da2b1f265682e63.f9f37c164718db9c218f.js 中的函数。这里我加的是【e == ‘321654’】的条件断点,防止其他地方调用此函数干扰判断:
在这里插入图片描述
该函数源码:

    aCH8: function(e, t, n) {
        !function() {
            var t = n("ANhw")
              , r = n("mmNF").utf8
              , o = n("BEtg")
              , i = n("mmNF").bin
              , s = function(e, n) {
                e.constructor == String ? e = n && "binary" === n.encoding ? i.stringToBytes(e) : r.stringToBytes(e) : o(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || (e = e.toString());
                for (var a = t.bytesToWords(e), u = 8 * e.length, c = 1732584193, f = -271733879, p = -1732584194, h = 271733878, l = 0; l < a.length; l++)
                    a[l] = 16711935 & (a[l] << 8 | a[l] >>> 24) | 4278255360 & (a[l] << 24 | a[l] >>> 8);
                a[u >>> 5] |= 128 << u % 32,
                a[14 + (u + 64 >>> 9 << 4)] = u;
                var d = s._ff
                  , y = s._gg
                  , m = s._hh
                  , g = s._ii;
                for (l = 0; l < a.length; l += 16) {
                    var v = c
                      , w = f
                      , x = p
                      , b = h;
                    c = d(c, f, p, h, a[l + 0], 7, -680876936),
                    h = d(h, c, f, p, a[l + 1], 12, -389564586),
                    p = d(p, h, c, f, a[l + 2], 17, 606105819),
                    f = d(f, p, h, c, a[l + 3], 22, -1044525330),
                    c = d(c, f, p, h, a[l + 4], 7, -176418897),
                    h = d(h, c, f, p, a[l + 5], 12, 1200080426),
                    p = d(p, h, c, f, a[l + 6], 17, -1473231341),
                    f = d(f, p, h, c, a[l + 7], 22, -45705983),
                    c = d(c, f, p, h, a[l + 8], 7, 1770035416),
                    h = d(h, c, f, p, a[l + 9], 12, -1958414417),
                    p = d(p, h, c, f, a[l + 10], 17, -42063),
                    f = d(f, p, h, c, a[l + 11], 22, -1990404162),
                    c = d(c, f, p, h, a[l + 12], 7, 1804603682),
                    h = d(h, c, f, p, a[l + 13], 12, -40341101),
                    p = d(p, h, c, f, a[l + 14], 17, -1502002290),
                    c = y(c, f = d(f, p, h, c, a[l + 15], 22, 1236535329), p, h, a[l + 1], 5, -165796510),
                    h = y(h, c, f, p, a[l + 6], 9, -1069501632),
                    p = y(p, h, c, f, a[l + 11], 14, 643717713),
                    f = y(f, p, h, c, a[l + 0], 20, -373897302),
                    c = y(c, f, p, h, a[l + 5], 5, -701558691),
                    h = y(h, c, f, p, a[l + 10], 9, 38016083),
                    p = y(p, h, c, f, a[l + 15], 14, -660478335),
                    f = y(f, p, h, c, a[l + 4], 20, -405537848),
                    c = y(c, f, p, h, a[l + 9], 5, 568446438),
                    h = y(h, c, f, p, a[l + 14], 9, -1019803690),
                    p = y(p, h, c, f, a[l + 3], 14, -187363961),
                    f = y(f, p, h, c, a[l + 8], 20, 1163531501),
                    c = y(c, f, p, h, a[l + 13], 5, -1444681467),
                    h = y(h, c, f, p, a[l + 2], 9, -51403784),
                    p = y(p, h, c, f, a[l + 7], 14, 1735328473),
                    c = m(c, f = y(f, p, h, c, a[l + 12], 20, -1926607734), p, h, a[l + 5], 4, -378558),
                    h = m(h, c, f, p, a[l + 8], 11, -2022574463),
                    p = m(p, h, c, f, a[l + 11], 16, 1839030562),
                    f = m(f, p, h, c, a[l + 14], 23, -35309556),
                    c = m(c, f, p, h, a[l + 1], 4, -1530992060),
                    h = m(h, c, f, p, a[l + 4], 11, 1272893353),
                    p = m(p, h, c, f, a[l + 7], 16, -155497632),
                    f = m(f, p, h, c, a[l + 10], 23, -1094730640),
                    c = m(c, f, p, h, a[l + 13], 4, 681279174),
                    h = m(h, c, f, p, a[l + 0], 11, -358537222),
                    p = m(p, h, c, f, a[l + 3], 16, -722521979),
                    f = m(f, p, h, c, a[l + 6], 23, 76029189),
                    c = m(c, f, p, h, a[l + 9], 4, -640364487),
                    h = m(h, c, f, p, a[l + 12], 11, -421815835),
                    p = m(p, h, c, f, a[l + 15], 16, 530742520),
                    c = g(c, f = m(f, p, h, c, a[l + 2], 23, -995338651), p, h, a[l + 0], 6, -198630844),
                    h = g(h, c, f, p, a[l + 7], 10, 1126891415),
                    p = g(p, h, c, f, a[l + 14], 15, -1416354905),
                    f = g(f, p, h, c, a[l + 5], 21, -57434055),
                    c = g(c, f, p, h, a[l + 12], 6, 1700485571),
                    h = g(h, c, f, p, a[l + 3], 10, -1894986606),
                    p = g(p, h, c, f, a[l + 10], 15, -1051523),
                    f = g(f, p, h, c, a[l + 1], 21, -2054922799),
                    c = g(c, f, p, h, a[l + 8], 6, 1873313359),
                    h = g(h, c, f, p, a[l + 15], 10, -30611744),
                    p = g(p, h, c, f, a[l + 6], 15, -1560198380),
                    f = g(f, p, h, c, a[l + 13], 21, 1309151649),
                    c = g(c, f, p, h, a[l + 4], 6, -145523070),
                    h = g(h, c, f, p, a[l + 11], 10, -1120210379),
                    p = g(p, h, c, f, a[l + 2], 15, 718787259),
                    f = g(f, p, h, c, a[l + 9], 21, -343485551),
                    c = c + v >>> 0,
                    f = f + w >>> 0,
                    p = p + x >>> 0,
                    h = h + b >>> 0
                }
                return t.endian([c, f, p, h])
            };
            s._ff = function(e, t, n, r, o, i, s) {
                var a = e + (t & n | ~t & r) + (o >>> 0) + s;
                return (a << i | a >>> 32 - i) + t
            }
            ,
            s._gg = function(e, t, n, r, o, i, s) {
                var a = e + (t & r | n & ~r) + (o >>> 0) + s;
                return (a << i | a >>> 32 - i) + t
            }
            ,
            s._hh = function(e, t, n, r, o, i, s) {
                var a = e + (t ^ n ^ r) + (o >>> 0) + s;
                return (a << i | a >>> 32 - i) + t
            }
            ,
            s._ii = function(e, t, n, r, o, i, s) {
                var a = e + (n ^ (t | ~r)) + (o >>> 0) + s;
                return (a << i | a >>> 32 - i) + t
            }
            ,
            s._blocksize = 16,
            s._digestsize = 16,
            e.exports = function(e, n) {
                if (void 0 === e || null === e)
                    throw new Error("Illegal argument " + e);
                var r = t.wordsToBytes(s(e, n));
                return n && n.asBytes ? r : n && n.asString ? i.bytesToString(r) : t.bytesToHex(r)
            }
        }()
    },

如果我们要直接调用这个函数模块,首先就要把代码开始的 n(“XXXX”) 代表的模块都“拿过来”。这里给出三种方案:

  1. 搜索“XXXX”模块名找到对应函数,缺点:模块名混淆后搜索结果过多时不好排查。
  2. 在 n(“XXXX”) 下断点,执行时定位到函数,缺点:webpack把所有代码打包进一个js,内容过多导致调试卡死。
  3. 在 n(“XXXX”) 使用 console.log() 插桩打印出函数,缺点:需要替换对应js文件响应,如果是动态地址响应,需要正则表达式,较为繁琐。

这里我们使用方案3,在开头 n(“XXXX”) 处插桩:

console.log("插桩开始------------------");
var t = n("ANhw");
console.log(n("ANhw"));
var r = n("mmNF").utf8;
console.log(n("mmNF"));
var o = n("BEtg");
console.log(n("BEtg"));
var i = n("mmNF").bin
console.log(n("mmNF"));
console.log("插桩结束------------------");

使用Fiddler的自动响应替换js文件请求返回我们插桩后的,该网站是静态地址,直接偷梁换柱:
在这里插入图片描述
清除缓存后刷新网页,成功请求到了我们替换的js:
在这里插入图片描述
控制台打印了各模块:
在这里插入图片描述
分别定位过去就能找到源码(这里以BEtg为例):

BEtg: function(e, t) {
    function n(e) {
        return !!e.constructor && "function" === typeof e.constructor.isBuffer && e.constructor.isBuffer(e)
    }
    e.exports = function(e) {
        return null != e && (n(e) || function(e) {
            return "function" === typeof e.readFloatLE && "function" === typeof e.slice && n(e.slice(0, 0))
        }(e) || !!e._isBuffer)
    }
},

要放进我们的代码里需要稍微改动一下,为了防止混淆的变量名冲突,这里用了闭包:

var BEtg = (function(e, t) {
    function n(e) {
        return !!e.constructor && "function" === typeof e.constructor.isBuffer && e.constructor.isBuffer(e)
    }
    return function(e) {
        return null != e && (n(e) || function(e) {
            return "function" === typeof e.readFloatLE && "function" === typeof e.slice && n(e.slice(0, 0))
        }(e) || !!e._isBuffer)
    }
})();

其他模块使用做类似修改,最终我们的js文件:

//ANhw
var ANhw = (function (e, t) {
    var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        , n = {
            rotl: function (e, t) {
                return e << t | e >>> 32 - t
            },
            rotr: function (e, t) {
                return e << 32 - t | e >>> t
            },
            endian: function (e) {
                if (e.constructor == Number)
                    return 16711935 & n.rotl(e, 8) | 4278255360 & n.rotl(e, 24);
                for (var t = 0; t < e.length; t++)
                    e[t] = n.endian(e[t]);
                return e
            },
            randomBytes: function (e) {
                for (var t = []; e > 0; e--)
                    t.push(Math.floor(256 * Math.random()));
                return t
            },
            bytesToWords: function (e) {
                for (var t = [], n = 0, r = 0; n < e.length; n++,
                    r += 8)
                    t[r >>> 5] |= e[n] << 24 - r % 32;
                return t
            },
            wordsToBytes: function (e) {
                for (var t = [], n = 0; n < 32 * e.length; n += 8)
                    t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
                return t
            },
            bytesToHex: function (e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push((e[n] >>> 4).toString(16)),
                        t.push((15 & e[n]).toString(16));
                return t.join("")
            },
            hexToBytes: function (e) {
                for (var t = [], n = 0; n < e.length; n += 2)
                    t.push(parseInt(e.substr(n, 2), 16));
                return t
            },
            bytesToBase64: function (e) {
                for (var n = [], r = 0; r < e.length; r += 3)
                    for (var o = e[r] << 16 | e[r + 1] << 8 | e[r + 2], i = 0; i < 4; i++)
                        8 * r + 6 * i <= 8 * e.length ? n.push(t.charAt(o >>> 6 * (3 - i) & 63)) : n.push("=");
                return n.join("")
            },
            base64ToBytes: function (e) {
                e = e.replace(/[^A-Z0-9+\/]/gi, "");
                for (var n = [], r = 0, o = 0; r < e.length; o = ++r % 4)
                    0 != o && n.push((t.indexOf(e.charAt(r - 1)) & Math.pow(2, -2 * o + 8) - 1) << 2 * o | t.indexOf(e.charAt(r)) >>> 6 - 2 * o);
                return n
            }
        };
    return n;
})();

//mmNF
var mmNF = (function (e, t) {
    var n = {
        utf8: {
            stringToBytes: function (e) {
                return n.bin.stringToBytes(unescape(encodeURIComponent(e)))
            },
            bytesToString: function (e) {
                return decodeURIComponent(escape(n.bin.bytesToString(e)))
            }
        },
        bin: {
            stringToBytes: function (e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push(255 & e.charCodeAt(n));
                return t
            },
            bytesToString: function (e) {
                for (var t = [], n = 0; n < e.length; n++)
                    t.push(String.fromCharCode(e[n]));
                return t.join("")
            }
        }
    };
    return n;
})();

//BEtg
var BEtg = (function (e, t) {
    function n(e) {
        return !!e.constructor && "function" === typeof e.constructor.isBuffer && e.constructor.isBuffer(e)
    }
    return function (e) {
        return null != e && (n(e) || function (e) {
            return "function" === typeof e.readFloatLE && "function" === typeof e.slice && n(e.slice(0, 0))
        }(e) || !!e._isBuffer)
    }
})();

//aCH8
var t = ANhw,
    r = mmNF.utf8,
    o = BEtg,
    i = mmNF.bin,
    s = function (e, n) {
        e.constructor == String ? e = n && "binary" === n.encoding ? i.stringToBytes(e) : r.stringToBytes(e) : o(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || (e = e.toString());
        for (var a = t.bytesToWords(e), u = 8 * e.length, c = 1732584193, f = -271733879, p = -1732584194, h = 271733878, l = 0; l < a.length; l++)
            a[l] = 16711935 & (a[l] << 8 | a[l] >>> 24) | 4278255360 & (a[l] << 24 | a[l] >>> 8);
        a[u >>> 5] |= 128 << u % 32,
            a[14 + (u + 64 >>> 9 << 4)] = u;
        var d = s._ff,
            y = s._gg,
            m = s._hh,
            g = s._ii;
        for (l = 0; l < a.length; l += 16) {
            var v = c
                , w = f
                , x = p
                , b = h;
            c = d(c, f, p, h, a[l + 0], 7, -680876936),
                h = d(h, c, f, p, a[l + 1], 12, -389564586),
                p = d(p, h, c, f, a[l + 2], 17, 606105819),
                f = d(f, p, h, c, a[l + 3], 22, -1044525330),
                c = d(c, f, p, h, a[l + 4], 7, -176418897),
                h = d(h, c, f, p, a[l + 5], 12, 1200080426),
                p = d(p, h, c, f, a[l + 6], 17, -1473231341),
                f = d(f, p, h, c, a[l + 7], 22, -45705983),
                c = d(c, f, p, h, a[l + 8], 7, 1770035416),
                h = d(h, c, f, p, a[l + 9], 12, -1958414417),
                p = d(p, h, c, f, a[l + 10], 17, -42063),
                f = d(f, p, h, c, a[l + 11], 22, -1990404162),
                c = d(c, f, p, h, a[l + 12], 7, 1804603682),
                h = d(h, c, f, p, a[l + 13], 12, -40341101),
                p = d(p, h, c, f, a[l + 14], 17, -1502002290),
                c = y(c, f = d(f, p, h, c, a[l + 15], 22, 1236535329), p, h, a[l + 1], 5, -165796510),
                h = y(h, c, f, p, a[l + 6], 9, -1069501632),
                p = y(p, h, c, f, a[l + 11], 14, 643717713),
                f = y(f, p, h, c, a[l + 0], 20, -373897302),
                c = y(c, f, p, h, a[l + 5], 5, -701558691),
                h = y(h, c, f, p, a[l + 10], 9, 38016083),
                p = y(p, h, c, f, a[l + 15], 14, -660478335),
                f = y(f, p, h, c, a[l + 4], 20, -405537848),
                c = y(c, f, p, h, a[l + 9], 5, 568446438),
                h = y(h, c, f, p, a[l + 14], 9, -1019803690),
                p = y(p, h, c, f, a[l + 3], 14, -187363961),
                f = y(f, p, h, c, a[l + 8], 20, 1163531501),
                c = y(c, f, p, h, a[l + 13], 5, -1444681467),
                h = y(h, c, f, p, a[l + 2], 9, -51403784),
                p = y(p, h, c, f, a[l + 7], 14, 1735328473),
                c = m(c, f = y(f, p, h, c, a[l + 12], 20, -1926607734), p, h, a[l + 5], 4, -378558),
                h = m(h, c, f, p, a[l + 8], 11, -2022574463),
                p = m(p, h, c, f, a[l + 11], 16, 1839030562),
                f = m(f, p, h, c, a[l + 14], 23, -35309556),
                c = m(c, f, p, h, a[l + 1], 4, -1530992060),
                h = m(h, c, f, p, a[l + 4], 11, 1272893353),
                p = m(p, h, c, f, a[l + 7], 16, -155497632),
                f = m(f, p, h, c, a[l + 10], 23, -1094730640),
                c = m(c, f, p, h, a[l + 13], 4, 681279174),
                h = m(h, c, f, p, a[l + 0], 11, -358537222),
                p = m(p, h, c, f, a[l + 3], 16, -722521979),
                f = m(f, p, h, c, a[l + 6], 23, 76029189),
                c = m(c, f, p, h, a[l + 9], 4, -640364487),
                h = m(h, c, f, p, a[l + 12], 11, -421815835),
                p = m(p, h, c, f, a[l + 15], 16, 530742520),
                c = g(c, f = m(f, p, h, c, a[l + 2], 23, -995338651), p, h, a[l + 0], 6, -198630844),
                h = g(h, c, f, p, a[l + 7], 10, 1126891415),
                p = g(p, h, c, f, a[l + 14], 15, -1416354905),
                f = g(f, p, h, c, a[l + 5], 21, -57434055),
                c = g(c, f, p, h, a[l + 12], 6, 1700485571),
                h = g(h, c, f, p, a[l + 3], 10, -1894986606),
                p = g(p, h, c, f, a[l + 10], 15, -1051523),
                f = g(f, p, h, c, a[l + 1], 21, -2054922799),
                c = g(c, f, p, h, a[l + 8], 6, 1873313359),
                h = g(h, c, f, p, a[l + 15], 10, -30611744),
                p = g(p, h, c, f, a[l + 6], 15, -1560198380),
                f = g(f, p, h, c, a[l + 13], 21, 1309151649),
                c = g(c, f, p, h, a[l + 4], 6, -145523070),
                h = g(h, c, f, p, a[l + 11], 10, -1120210379),
                p = g(p, h, c, f, a[l + 2], 15, 718787259),
                f = g(f, p, h, c, a[l + 9], 21, -343485551),
                c = c + v >>> 0,
                f = f + w >>> 0,
                p = p + x >>> 0,
                h = h + b >>> 0
        }
        return t.endian([c, f, p, h])
    };
s._ff = function (e, t, n, r, o, i, s) {
    var a = e + (t & n | ~t & r) + (o >>> 0) + s;
    return (a << i | a >>> 32 - i) + t
},
    s._gg = function (e, t, n, r, o, i, s) {
        var a = e + (t & r | n & ~r) + (o >>> 0) + s;
        return (a << i | a >>> 32 - i) + t
    },
    s._hh = function (e, t, n, r, o, i, s) {
        var a = e + (t ^ n ^ r) + (o >>> 0) + s;
        return (a << i | a >>> 32 - i) + t
    },
    s._ii = function (e, t, n, r, o, i, s) {
        var a = e + (n ^ (t | ~r)) + (o >>> 0) + s;
        return (a << i | a >>> 32 - i) + t
    },
    s._blocksize = 16,
    s._digestsize = 16,

    MD5 = function (e, n) { //e.exports改为函数名方便调用
        if (void 0 === e || null === e)
            throw new Error("Illegal argument " + e);
        var r = t.wordsToBytes(s(e, n));
        return n && n.asBytes ? r : n && n.asString ? i.bytesToString(r) : t.bytesToHex(r)
    }

//测试调用
let res = MD5("321654");
console.log(res);

运行,正确打印了加密后的password。其实这套算法只是对password做了MD5而已:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到