【QQ音乐】sign签名| data参数 | AES-GCM加密 | webpack(上)

1.目标

网址:https://y.qq.com/n/ryqq/toplist/26


切换榜单出现请求,可以看到sign和data是加密的

2.逆向分析

搜索sign:

可以看到sign = P(n.data),而n.data就是请求的加密data参数

javascript 复制代码
data = '{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":0,"g_tk_new_20200303":5381,"g_tk":5381},"req_1":{"module":"musicToplist.ToplistInfoServer","method":"GetDetail","param":{"topid":27,"offset":0,"num":20,"period":"2025-05-27"}}}'

3.webpack分析

这是Webpack 打包后的模块加载代码

在这里打上断点找加载器n,然后刷新页面

可以看到加载器的name是"f",数组m里面390个模块

点击进入就是加载器

可以看到是以列表的方式存储模块的,

然后将获取sign的模块,就是含有下面内容的模块,放进去

javascript 复制代码
var P = G._getSecuritySign;
var L = j.__cgiEncrypt
 , N = j.__cgiDecrypt;
  • G._getSecuritySign
    • 获取sign
  • j.__cgiEncrypt
    • 加密请求参数data
  • j.__cgiDecrypt
    • 解密响应二进制数据
javascript 复制代码
window = global;

!function(e) {
    function r() {
        for (var e, t = 0; t < d.length; t++) {
            for (var r = d[t], a = !0, n = 1; n < r.length; n++) {
                var c = r[n];
                0 !== o[c] && (a = !1)
            }
            a && (d.splice(t--, 1),
            e = f(f.s = r[0]))
        }
        return e
    }
    var a = {}
      , n = {
        21: 0
    }
      , o = {
        21: 0
    }
      , d = [];
    function f(t) {
        if (a[t])
            return a[t].exports;
        var r = a[t] = {
            i: t,
            l: !1,
            exports: {}
        };
        console.log(t)
        return e[t].call(r.exports, r, r.exports, f),
        r.l = !0,
        r.exports
    }
    f.m = e,
    f.c = a,
    f.d = function(e, t, r) {
        f.o(e, t) || Object.defineProperty(e, t, {
            enumerable: !0,
            get: r
        })
    }
    ,
    f.r = function(e) {
        "undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
            value: "Module"
        }),
        Object.defineProperty(e, "__esModule", {
            value: !0
        })
    }
    ,
    f.t = function(e, t) {
        if (1 & t && (e = f(e)),
        8 & t)
            return e;
        if (4 & t && "object" === typeof e && e && e.__esModule)
            return e;
        var r = Object.create(null);
        if (f.r(r),
        Object.defineProperty(r, "default", {
            enumerable: !0,
            value: e
        }),
        2 & t && "string" != typeof e)
            for (var a in e)
                f.d(r, a, function(t) {
                    return e[t]
                }
                .bind(null, a));
        return r
    }
    ,

    f.o = function(e, t) {
        return Object.prototype.hasOwnProperty.call(e, t)
    }
    
    r()
    window.shark = f;
}([]);

console.log(window.shark);

先删除一些无用的代码,然后将模块放进去

如果这么运行的话,毫无疑问是会报错的

javascript 复制代码
        return e[t].call(r.exports, r, r.exports, f),
                    ^

TypeError: Cannot read properties of undefined (reading 'call')

很明显缺少的是下标为81的模块,然后我们去浏览器取该模块

然后这里也不是导入81模块,在这里我们是导入自己的下标为1的模块

然后接下来就是导出全局函数了

打印方法没有问题

4.sign验证

javascript 复制代码
get_sign = (data) => window.shark(0).getSign(data);

data = '{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":0,"g_tk_new_20200303":5381,"g_tk":5381},"req_1":{"module":"musicToplist.ToplistInfoServer","method":"GetDetail","param":{"topid":27,"offset":0,"num":20,"period":"2025-05-28"}}}'

console.log(get_sign(data))

写个箭头函数验证能否生成sign

运行代码可以生成sign

但是和浏览器的sign不一样,而且data是一样的,这就是缺少必要的环境

javascript 复制代码
window = global;

document = {
    cookie: 'pgv_pvid=592785550; fqm_pvqid=75e53579-6875-45e3-9bfa-8c3634fd8b23; fqm_sessionid=4742d993-b7c2-4148-b070-67c2ac322bc7; pgv_info=ssid=s6945372512; ts_last=y.qq.com/n/ryqq/toplist/26; ts_refer=cn.bing.com/; ts_uid=4872983500',
    createElement: function(res){
        if(res == 'a') return {}
    },
}
navigator = {
    userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",

}
location = {
    "href": "https://y.qq.com/",
    "host": "y.qq.com",
}

补充环境之后发现和浏览器的一致

sign算法逆向参见:https://blog.csdn.net/2406_83321119/article/details/146435985

相关推荐
白帽攻防录3 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛3 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148114 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
xixiaoyunya4 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的5 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务5 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
打工仔折腾 AI7 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战
MATLAB代码顾问7 小时前
Simulink PI 参数扫描与批量仿真完整 MATLAB 代码
开发语言·matlab
Want5957 小时前
Python跳动的爱心②
开发语言·python·数学建模
小羊没烦恼!8 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html