• JS逆向-新榜数据nonce和xyz参数分析


    分析网站: https://www.newrank.cn/public/info/list.html?period=week&type=data

    这次我们要分析的是该网站的接口中的noncexyz参数。
    (好久不玩js,都有点遗忘了,记录下调试的过程,菜鸡小白一枚多多指教!)

    1.首先我们抓个包:

    打开network,然后选择XHR,找到这个rank榜单的接口:https://www.newrank.cn/xdnphb/main/v1/week/rank

    可以看到这里有两个参数noncexyz。经过多次的测试,发现每次请求的时候,这两个参数都会发生变化,所以我们大胆的猜测他们肯定是加密的。

    在这里插入图片描述
    老规矩,还是先搜索关键词nonce,然后在逐一分析每个js文件,点进去看一下。

    在这里插入图片描述

    先点到第一个js文件看下,然后我们来到了这里。

    在这里插入图片描述

    看代码的命名风格很像,我们接着打个断点,接着刷新页面,看看断点会不会断进去。

    在这里插入图片描述

    看样子,我们是成功的把断点下进去了。

    这里我们看到 j() 方法的返回值是a276726d4,和nonce参数好像。

    是的,没错这里就是核心加密的地方。

    最核心的js代码如下:

    var i = j();
    return g.nonce = i,
            h += "&nonce=" + i,
            g.xyz = d(h),
    
    • 1
    • 2
    • 3
    • 4

    我们先来简答的分析,其中定义一个变量叫 i ,然后把j()方法的返回值当做i,

    然后把i又赋值给nonce参数,紧接着又把原本的h再加上nonce参数组合成新的h参数,

    最后经过d(h)方法把返回值赋给xyz

    2.一步一步分析

    断点调试的模式中,在控制台console直接输入对应的方法名称,能直接跳转到对应的函数位置,

    就像上图中输入j一样,紧接着跳转过去。

    在这里插入图片描述
    我们把这段js代码抠出来如下,

    function j() {
        for (var a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"], b = 0; b < 500; b++)
            for (var c = "", d = 0; d < 9; d++) {
                var e = Math.floor(16 * Math.random());
                c += a[e]
            }
        return c
    }
    console.log("获取nonce:", j())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    然后在webstrom跑一下,成功的跑出来了。

    在这里插入图片描述

    接着我们分析d(h) 方法。

    断点来到这里,查看h到底是个什么值,

    在控制台打印下:/xdnphb/nr/cloud/douyin/conllect/listNrDouyinDataVO?AppKey=joker&nonce=dbabca0b9

    简单的理解就是请求url的后半部分拼接个AppKey=joker

    然后又拼接个nonce,这个nonce就是上面👆🏻那个j()的返回值。

    在这里插入图片描述

    那么d()方法到底是什么,我们跳转进去看一下。

    在这里插入图片描述
    又来到了这里。

     function b(a) {
            function b(a) {
                return d(c(e(a)))
            }
            function c(a) {
                return g(h(f(a), 8 * a.length))
            }
            function d(a) {
                for (var b, c = p ? "0123456789ABCDEF" : "0123456789abcdef", d = "", e = 0; e < a.length; e++)
                    b = a.charCodeAt(e),
                    d += c.charAt(b >>> 4 & 15) + c.charAt(15 & b);
                return d
            }
            后面还有一大堆代码省略了。。。。。。。。。。。。。。。。。太长了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    嗯具体的计算逻辑,暂时先不用关心,我们只管抠js代码,然后在补运行环境。

    再用webstorm跑一下,看看结果,没有报错很开心,嘻嘻嘻嘻。

    在这里插入图片描述

    可以看到输入的值是

    /xdnphb/nr/cloud/douyin/conllect/listNrDouyinDataVO?AppKey=joker&nonce=dbabca0b9
    
    • 1

    返回的结果是99b4466183158bb83d29846dca52fb49

    和我们在断点调试看到的值一模一样,这说明我们分析对了。

    以上只是我们js跑出来的结果是一样的,但实际到底是不是正确的尼。

    3.实际测试

    就它吧

    在这里插入图片描述
    在这里插入图片描述
    这里h也就是加密前的参数是:

    /xdnphb/main/v1/week/rank?AppKey=joker&end=2022-10-23&rank_name=科技&rank_name_group=资讯&start=2022-10-17&nonce=88afb83b0
    
    • 1

    在这里插入图片描述
    嗯返回的加密数据一致。

    4.贴下源码

    js代码如下:

    function get_nonce() {
        for (var a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"], b = 0; b < 500; b++)
            for (var c = "", d = 0; d < 9; d++) {
                var e = Math.floor(16 * Math.random());
                c += a[e]
            }
        return c
    }
    
    function get_xyz(a) {
        function b(a) {
            return d(c(e(a)))
        }
        function c(a) {
            return g(h(f(a), 8 * a.length))
        }
        function d(a) {
            for (var b, c = p ? "0123456789ABCDEF" : "0123456789abcdef", d = "", e = 0; e < a.length; e++)
                b = a.charCodeAt(e),
                    d += c.charAt(b >>> 4 & 15) + c.charAt(15 & b);
            return d
        }
        function e(a) {
            for (var b, c, d = "", e = -1; ++e < a.length; )
                b = a.charCodeAt(e),
                    c = e + 1 < a.length ? a.charCodeAt(e + 1) : 0,
                55296 <= b && b <= 56319 && 56320 <= c && c <= 57343 && (b = 65536 + ((1023 & b) << 10) + (1023 & c),
                    e++),
                    b <= 127 ? d += String.fromCharCode(b) : b <= 2047 ? d += String.fromCharCode(192 | b >>> 6 & 31, 128 | 63 & b) : b <= 65535 ? d += String.fromCharCode(224 | b >>> 12 & 15, 128 | b >>> 6 & 63, 128 | 63 & b) : b <= 2097151 && (d += String.fromCharCode(240 | b >>> 18 & 7, 128 | b >>> 12 & 63, 128 | b >>> 6 & 63, 128 | 63 & b));
            return d
        }
        function f(a) {
            for (var b = Array(a.length >> 2), c = 0; c < b.length; c++)
                b[c] = 0;
            for (var c = 0; c < 8 * a.length; c += 8)
                b[c >> 5] |= (255 & a.charCodeAt(c / 8)) << c % 32;
            return b
        }
        function g(a) {
            for (var b = "", c = 0; c < 32 * a.length; c += 8)
                b += String.fromCharCode(a[c >> 5] >>> c % 32 & 255);
            return b
        }
        function h(a, b) {
            a[b >> 5] |= 128 << b % 32,
                a[14 + (b + 64 >>> 9 << 4)] = b;
            for (var c = 1732584193, d = -271733879, e = -1732584194, f = 271733878, g = 0; g < a.length; g += 16) {
                var h = c
                    , i = d
                    , o = e
                    , p = f;
                c = j(c, d, e, f, a[g + 0], 7, -680876936),
                    f = j(f, c, d, e, a[g + 1], 12, -389564586),
                    e = j(e, f, c, d, a[g + 2], 17, 606105819),
                    d = j(d, e, f, c, a[g + 3], 22, -1044525330),
                    c = j(c, d, e, f, a[g + 4], 7, -176418897),
                    f = j(f, c, d, e, a[g + 5], 12, 1200080426),
                    e = j(e, f, c, d, a[g + 6], 17, -1473231341),
                    d = j(d, e, f, c, a[g + 7], 22, -45705983),
                    c = j(c, d, e, f, a[g + 8], 7, 1770035416),
                    f = j(f, c, d, e, a[g + 9], 12, -1958414417),
                    e = j(e, f, c, d, a[g + 10], 17, -42063),
                    d = j(d, e, f, c, a[g + 11], 22, -1990404162),
                    c = j(c, d, e, f, a[g + 12], 7, 1804603682),
                    f = j(f, c, d, e, a[g + 13], 12, -40341101),
                    e = j(e, f, c, d, a[g + 14], 17, -1502002290),
                    d = j(d, e, f, c, a[g + 15], 22, 1236535329),
                    c = k(c, d, e, f, a[g + 1], 5, -165796510),
                    f = k(f, c, d, e, a[g + 6], 9, -1069501632),
                    e = k(e, f, c, d, a[g + 11], 14, 643717713),
                    d = k(d, e, f, c, a[g + 0], 20, -373897302),
                    c = k(c, d, e, f, a[g + 5], 5, -701558691),
                    f = k(f, c, d, e, a[g + 10], 9, 38016083),
                    e = k(e, f, c, d, a[g + 15], 14, -660478335),
                    d = k(d, e, f, c, a[g + 4], 20, -405537848),
                    c = k(c, d, e, f, a[g + 9], 5, 568446438),
                    f = k(f, c, d, e, a[g + 14], 9, -1019803690),
                    e = k(e, f, c, d, a[g + 3], 14, -187363961),
                    d = k(d, e, f, c, a[g + 8], 20, 1163531501),
                    c = k(c, d, e, f, a[g + 13], 5, -1444681467),
                    f = k(f, c, d, e, a[g + 2], 9, -51403784),
                    e = k(e, f, c, d, a[g + 7], 14, 1735328473),
                    d = k(d, e, f, c, a[g + 12], 20, -1926607734),
                    c = l(c, d, e, f, a[g + 5], 4, -378558),
                    f = l(f, c, d, e, a[g + 8], 11, -2022574463),
                    e = l(e, f, c, d, a[g + 11], 16, 1839030562),
                    d = l(d, e, f, c, a[g + 14], 23, -35309556),
                    c = l(c, d, e, f, a[g + 1], 4, -1530992060),
                    f = l(f, c, d, e, a[g + 4], 11, 1272893353),
                    e = l(e, f, c, d, a[g + 7], 16, -155497632),
                    d = l(d, e, f, c, a[g + 10], 23, -1094730640),
                    c = l(c, d, e, f, a[g + 13], 4, 681279174),
                    f = l(f, c, d, e, a[g + 0], 11, -358537222),
                    e = l(e, f, c, d, a[g + 3], 16, -722521979),
                    d = l(d, e, f, c, a[g + 6], 23, 76029189),
                    c = l(c, d, e, f, a[g + 9], 4, -640364487),
                    f = l(f, c, d, e, a[g + 12], 11, -421815835),
                    e = l(e, f, c, d, a[g + 15], 16, 530742520),
                    d = l(d, e, f, c, a[g + 2], 23, -995338651),
                    c = m(c, d, e, f, a[g + 0], 6, -198630844),
                    f = m(f, c, d, e, a[g + 7], 10, 1126891415),
                    e = m(e, f, c, d, a[g + 14], 15, -1416354905),
                    d = m(d, e, f, c, a[g + 5], 21, -57434055),
                    c = m(c, d, e, f, a[g + 12], 6, 1700485571),
                    f = m(f, c, d, e, a[g + 3], 10, -1894986606),
                    e = m(e, f, c, d, a[g + 10], 15, -1051523),
                    d = m(d, e, f, c, a[g + 1], 21, -2054922799),
                    c = m(c, d, e, f, a[g + 8], 6, 1873313359),
                    f = m(f, c, d, e, a[g + 15], 10, -30611744),
                    e = m(e, f, c, d, a[g + 6], 15, -1560198380),
                    d = m(d, e, f, c, a[g + 13], 21, 1309151649),
                    c = m(c, d, e, f, a[g + 4], 6, -145523070),
                    f = m(f, c, d, e, a[g + 11], 10, -1120210379),
                    e = m(e, f, c, d, a[g + 2], 15, 718787259),
                    d = m(d, e, f, c, a[g + 9], 21, -343485551),
                    c = n(c, h),
                    d = n(d, i),
                    e = n(e, o),
                    f = n(f, p)
            }
            return Array(c, d, e, f)
        }
        function i(a, b, c, d, e, f) {
            return n(o(n(n(b, a), n(d, f)), e), c)
        }
        function j(a, b, c, d, e, f, g) {
            return i(b & c | ~b & d, a, b, e, f, g)
        }
        function k(a, b, c, d, e, f, g) {
            return i(b & d | c & ~d, a, b, e, f, g)
        }
        function l(a, b, c, d, e, f, g) {
            return i(b ^ c ^ d, a, b, e, f, g)
        }
        function m(a, b, c, d, e, f, g) {
            return i(c ^ (b | ~d), a, b, e, f, g)
        }
        function n(a, b) {
            var c = (65535 & a) + (65535 & b);
            return (a >> 16) + (b >> 16) + (c >> 16) << 16 | 65535 & c
        }
        function o(a, b) {
            return a << b | a >>> 32 - b
        }
        var p = 0;
        return b(a)
    }
    
    
    
    
    // var nonce = "/xdnphb/main/v1/day/rank?AppKey=joker&end=2022-10-27&rank_name=文化&rank_name_group=生活&start=2022-10-27&nonce=f8b9aa1ff";
    var nonce = "/xdnphb/main/v1/day/rank?AppKey=joker&end=2022-10-27&rank_name=文化&rank_name_group=生活&start=2022-10-27&nonce=f8b9aa1ff"
    
    var xyz = get_xyz(nonce);
    console.log("获取xyz:", xyz);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156

    python代码如下:

    import requests
    import execjs
    from urllib import parse
    
    with open("sign.js", "r", encoding="utf-8") as f:
        js_code = f.read()
        ctx = execjs.compile(js_code)
    
    
    def get_nonce():
        return ctx.call("get_nonce")
    
    
    def map_to_str(map_):
        return "&".join([f"{i}={map_[i]}" for i in map_])
    
    
    def map_to_str_quote(map_):
        return "&".join([f"{i}={parse.quote(map_[i])}" for i in map_])
    
    
    def get_xyz(url, map_dict):
        url = url.replace("https://www.newrank.cn", "")
        url += "?AppKey=joker&"
    
        url += map_to_str(map_dict)
        return ctx.call("get_xyz", url)
    
    
    if __name__ == "__main__":
    
        rank_url = "https://www.newrank.cn/xdnphb/main/v1/week/rank"
        headers = {
            "authority": "www.newrank.cn",
            "accept": "application/json, text/javascript, */*; q=0.01",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "cache-control": "no-cache",
            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
            "origin": "https://www.newrank.cn",
            "pragma": "no-cache",
            "sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"macOS"',
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36",
            "x-requested-with": "XMLHttpRequest",
        }
        # nonce = get_nonce()
        nonce = "88afb83b0"
        payload = {
            "end": "2022-10-23",
            "rank_name": "科技",
            "rank_name_group": "资讯",
            "start": "2022-10-17",
            "nonce": nonce,
        }
        xyz = get_xyz(rank_url, payload)
        print("nonce:", nonce)
        print("xyz:", xyz)
        payload.update({"xyz": xyz})
    
        payload_str = map_to_str_quote(payload)
        response = requests.request("POST", rank_url, headers=headers, data=payload_str)
    
        print(response.text)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    运行结果:

    在这里插入图片描述

    完事手工下一个。

    参考博文:
    https://blog.csdn.net/weixin_43582101/article/details/118668174
    https://mp.weixin.qq.com/s/nG3i8SdmCczER_QvmbIt_Q

  • 相关阅读:
    Maika 与越南童模们受邀请参加中国上海时装周 hanakimi 品牌开幕
    数组去重
    华为云arm架构的linux系统中通过docker部署python环境
    星途星纪元 ES,用艺术思维表达工程技术
    i.MX6ULL驱动开发 | 33 - NXP原厂网络设备驱动浅读(LAN8720 PHY)
    树形DP总结
    oracle常用命令
    RocketMQ并行消费浅析
    Linux 网络编程
    【视觉高级篇】18 # 如何生成简单动画让图形动起来?
  • 原文地址:https://blog.csdn.net/weixin_38819889/article/details/127577020