JS逆向-某信公众平台pwd参数解密

174 阅读4分钟
😀 某信公众平台的pwd参数就像一道神秘的密码题,通过逆向破解它,就像解开了一个加密的笑话。抓包、分析代码,破解加密,瞬间从“看不懂”到“我懂了”,瞬间变成密码大师!

网址:aHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tLw==

分析过程

调出开发者工具,切换到network模块,随便输入一个账号和密码,抓包。

image.png

看到pwd参数被加密了,接下来就是去找到pwd参数的加密过程。但其实这里可以进行加密方法的猜测,密码处随便输入,抓包。

image.png转存失败,建议直接上传图片文件

下一步操作是通过搜索网址中的关键字来定位加密的部分。

image.png转存失败,建议直接上传图片文件

但在发现并不容易找到加密的具体位置。

于是,我转而使用了 initiator(初始器)来帮助定位问题。

image.png转存失败,建议直接上传图片文件

这是整个栈的调用过程,越靠上调用的越迟,所以从这张图中可以看出,堆栈从底部到顶部是按调用的顺序排列的。越靠上的函数表示越晚被调用,越底部的则是较早的函数,点击最上面的函数进入。

image.png转存失败,建议直接上传图片文件

在该行打个断点,再次输入账号和密码,点击登录,让程序停在断点处。

image.png转存失败,建议直接上传图片文件

从这个调试过程我们可以知道m就是最后发包的参数,我们要处理的就是pwd这个参数。

username=111&pwd=b59c67bf196a4758191e42f76670ceba&verify_ticket=&rand_str=&f=json&userlang=zh_CN&redirect_url=&token=&lang=zh_CN&ajax=1

参数已经加过密了,说明加密的逻辑不在这里,通过call stack往上找。

image.png转存失败,建议直接上传图片文件

这里我们要一层一层点击,切记不要心急。

image.png转存失败,建议直接上传图片文件

那有人会问,怎么确定是不是在这个函数实现的,那你可以参考函数的传入的参数是否是原模原样的字符串。

image.png转存失败,建议直接上传图片文件

我们可以看到不是,那就继续找,注意!!!这里只是参考,不一定是对的,最好对函数也阅读一遍(如果代码可读性还OK的话)

image.png转存失败,建议直接上传图片文件

其实到这里就很明显了。这里的pwd明显通过v这个函数继续计算得到的。

image.png转存失败,建议直接上传图片文件

这里还对密码继续了处理

a.pwd.substr(0, 16)

的值是123456,而

v(a.pwd.substr(0, 16))

然后值是e10adc3949ba59abbe56e057f20f883

重新打个断点,然后点击登录

image.png转存失败,建议直接上传图片文件

然后继续跟

image.png转存失败,建议直接上传图片文件

到这里就是加密的最终位置入口了。

image.png转存失败,建议直接上传图片文件

下一步就是模拟这个加密,把这个函数复制出来,然后把他所需要的函数复制出来,补回去,这样就可以实现完整的加密了。

function L(t) {
    return u(o(b(t), t.length * 8))
}

function h(t, i) {
    var r, f = b(t), j = [], O = [], $;
    j[15] = O[15] = void 0;
    if (f.length > 16) {
        f = o(f, t.length * 8)
    }
    for (r = 0; r < 16; r += 1) {
        j[r] = f[r] ^ 909522486;
        O[r] = f[r] ^ 1549556828
    }
    $ = o(j.concat(b(i)), 512 + i.length * 8);
    return u(o(O.concat($), 512 + 128))
}

function y(t) {
    var i = "0123456789abcdef", r = "", f, j;
    for (j = 0; j < t.length; j += 1) {
        f = t.charCodeAt(j);
        r += i.charAt(f >>> 4 & 15) + i.charAt(f & 15)
    }
    return r
}

function I(t) {
    return unescape(encodeURIComponent(t))
}

function E(t) {
    return L(I(t))
}

function P(t) {
    return y(E(t))
}

function _(t, i) {
    var r = (t & 65535) + (i & 65535), f = (t >> 16) + (i >> 16) + (r >> 16);
    return f << 16 | r & 65535
}

function x(t, i) {
    return t << i | t >>> 32 - i
}

function C(t, i, r, f, j, O) {
    return _(x(_(_(i, t), _(f, O)), j), r)
}

function S(t, i, r, f, j, O, $) {
    return C(i & r | ~i & f, t, i, j, O, $)
}

function d(t, i, r, f, j, O, $) {
    return C(i & f | r & ~f, t, i, j, O, $)
}

function g(t, i, r, f, j, O, $) {
    return C(i ^ r ^ f, t, i, j, O, $)
}

function v(t, i, r, f, j, O, $) {
    return C(r ^ (i | ~f), t, i, j, O, $)
}

function u(t) {
    var i, r = "";
    for (i = 0; i < t.length * 32; i += 8) {
        r += String.fromCharCode(t[i >> 5] >>> i % 32 & 255)
    }
    return r
}

function o(t, i) {
    t[i >> 5] |= 128 << i % 32;
    t[(i + 64 >>> 9 << 4) + 14] = i;
    var r, f, j, O, $, s = 1732584193, c = -271733879, m = -1732584194, n = 271733878;
    for (r = 0; r < t.length; r += 16) {
        f = s;
        j = c;
        O = m;
        $ = n;
        s = S(s, c, m, n, t[r], 7, -680876936);
        n = S(n, s, c, m, t[r + 1], 12, -389564586);
        m = S(m, n, s, c, t[r + 2], 17, 606105819);
        c = S(c, m, n, s, t[r + 3], 22, -1044525330);
        s = S(s, c, m, n, t[r + 4], 7, -176418897);
        n = S(n, s, c, m, t[r + 5], 12, 1200080426);
        m = S(m, n, s, c, t[r + 6], 17, -1473231341);
        c = S(c, m, n, s, t[r + 7], 22, -45705983);
        s = S(s, c, m, n, t[r + 8], 7, 1770035416);
        n = S(n, s, c, m, t[r + 9], 12, -1958414417);
        m = S(m, n, s, c, t[r + 10], 17, -42063);
        c = S(c, m, n, s, t[r + 11], 22, -1990404162);
        s = S(s, c, m, n, t[r + 12], 7, 1804603682);
        n = S(n, s, c, m, t[r + 13], 12, -40341101);
        m = S(m, n, s, c, t[r + 14], 17, -1502002290);
        c = S(c, m, n, s, t[r + 15], 22, 1236535329);
        s = d(s, c, m, n, t[r + 1], 5, -165796510);
        n = d(n, s, c, m, t[r + 6], 9, -1069501632);
        m = d(m, n, s, c, t[r + 11], 14, 643717713);
        c = d(c, m, n, s, t[r], 20, -373897302);
        s = d(s, c, m, n, t[r + 5], 5, -701558691);
        n = d(n, s, c, m, t[r + 10], 9, 38016083);
        m = d(m, n, s, c, t[r + 15], 14, -660478335);
        c = d(c, m, n, s, t[r + 4], 20, -405537848);
        s = d(s, c, m, n, t[r + 9], 5, 568446438);
        n = d(n, s, c, m, t[r + 14], 9, -1019803690);
        m = d(m, n, s, c, t[r + 3], 14, -187363961);
        c = d(c, m, n, s, t[r + 8], 20, 1163531501);
        s = d(s, c, m, n, t[r + 13], 5, -1444681467);
        n = d(n, s, c, m, t[r + 2], 9, -51403784);
        m = d(m, n, s, c, t[r + 7], 14, 1735328473);
        c = d(c, m, n, s, t[r + 12], 20, -1926607734);
        s = g(s, c, m, n, t[r + 5], 4, -378558);
        n = g(n, s, c, m, t[r + 8], 11, -2022574463);
        m = g(m, n, s, c, t[r + 11], 16, 1839030562);
        c = g(c, m, n, s, t[r + 14], 23, -35309556);
        s = g(s, c, m, n, t[r + 1], 4, -1530992060);
        n = g(n, s, c, m, t[r + 4], 11, 1272893353);
        m = g(m, n, s, c, t[r + 7], 16, -155497632);
        c = g(c, m, n, s, t[r + 10], 23, -1094730640);
        s = g(s, c, m, n, t[r + 13], 4, 681279174);
        n = g(n, s, c, m, t[r], 11, -358537222);
        m = g(m, n, s, c, t[r + 3], 16, -722521979);
        c = g(c, m, n, s, t[r + 6], 23, 76029189);
        s = g(s, c, m, n, t[r + 9], 4, -640364487);
        n = g(n, s, c, m, t[r + 12], 11, -421815835);
        m = g(m, n, s, c, t[r + 15], 16, 530742520);
        c = g(c, m, n, s, t[r + 2], 23, -995338651);
        s = v(s, c, m, n, t[r], 6, -198630844);
        n = v(n, s, c, m, t[r + 7], 10, 1126891415);
        m = v(m, n, s, c, t[r + 14], 15, -1416354905);
        c = v(c, m, n, s, t[r + 5], 21, -57434055);
        s = v(s, c, m, n, t[r + 12], 6, 1700485571);
        n = v(n, s, c, m, t[r + 3], 10, -1894986606);
        m = v(m, n, s, c, t[r + 10], 15, -1051523);
        c = v(c, m, n, s, t[r + 1], 21, -2054922799);
        s = v(s, c, m, n, t[r + 8], 6, 1873313359);
        n = v(n, s, c, m, t[r + 15], 10, -30611744);
        m = v(m, n, s, c, t[r + 6], 15, -1560198380);
        c = v(c, m, n, s, t[r + 13], 21, 1309151649);
        s = v(s, c, m, n, t[r + 4], 6, -145523070);
        n = v(n, s, c, m, t[r + 11], 10, -1120210379);
        m = v(m, n, s, c, t[r + 2], 15, 718787259);
        c = v(c, m, n, s, t[r + 9], 21, -343485551);
        s = _(s, f);
        c = _(c, j);
        m = _(m, O);
        n = _(n, $)
    }
    return [s, c, m, n]
}

function b(t) {
    var i, r = [];
    r[(t.length >> 2) - 1] = void 0;
    for (i = 0; i < r.length; i += 1) {
        r[i] = 0
    }
    for (i = 0; i < t.length * 8; i += 8) {
        r[i >> 5] |= (t.charCodeAt(i / 8) & 255) << i % 32
    }
    return r
};

console.log(P("1111"))

测试一下。

image.png转存失败,建议直接上传图片文件

看到跟他算出来是一模一样的。

接下来是高手的解法。

Python还原

他这个其实就是一个md5加密,我们可以看到他的位数是32位,有经验其实在抓包哪一步骤就猜出来了。我们可以直接用python还原。

import hashlib

def md5_encrypt(input_string):
    # 创建MD5对象
    md5 = hashlib.md5()

    # 更新加密对象,输入需要加密的字符串
    md5.update(input_string.encode('utf-8'))

    # 获取加密后的十六进制结果
    encrypted_string = md5.hexdigest()

    return encrypted_string

# 示例
input_data = "1111"
encrypted_data = md5_encrypt(input_data)
print(f"MD5加密后的结果: {encrypted_data}")

然后我们在运行对比。

image.png转存失败,建议直接上传图片文件

可以看到完全是一样的,所以这里就完整的实现加密流程了,代码运行速度还快,不过以上的nodejs扣代码也是需要去熟悉的,可以当做练手项目。

科技新生活.png