前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS逆向之网易云音乐

JS逆向之网易云音乐

作者头像
老肥码码码
发布2020-01-17 11:32:13
2.4K0
发布2020-01-17 11:32:13
举报
文章被收录于专栏:算法与数据之美

最近有一部很火的青春励志言情剧《亲爱的,热爱的》,其主人公之一佟年是一个网络歌手,其粉丝足有百万。好奇的我一搜,网易云音乐真有这么一号人物,真是现实和电视剧傻傻分不清楚。于是我就想着爬一下网易云音乐,分析一波这真假粉丝,(因为我觉得这个粉丝数目肯定存在刷粉丝的嫌疑~)。

虽然通过观察分析发现,只能爬取前50页的粉丝也就是1000个最新的粉丝,用于数据分析必然是没有成效的,但还是记录一下破解网易云音乐反爬的过程。

打开粉丝的页面,发现其是一个POST请求,包含params和encSecKey两个表单数据,而这个数据显然是经过了加密,我们需要进入js来一看究竟。

在js中搜索encSecKey发现这两个表单数据应该就在下图所示的函数中。

代码语言:javascript
复制
var bXY4c = window.asrsea(JSON.stringify(i3x), bqu5z(["流泪", "强"]), bqu5z(QE7x.md), bqu5z(["爱心", "女孩", "惊恐", "大笑"]));

params和encSecKey都是由window.asrea这个函数生成的,其一共包含四个参数,其中第二个参数中QE7x.md是固定的,和第二个第四个加密方式相同。(这wyy前端究竟是有什么样的故事,“流泪”,“女孩”,“惊恐”,“大笑”,莫名诡异)

代码语言:javascript
复制
    QE7x.md = ["色", "流感", "这边", "弱", "嘴唇", "亲", "开心", "呲牙", "憨笑", "猫", "皱眉", "幽灵", "蛋糕", "发怒", "大哭", "兔子", "星星", "钟情", "牵手", "公鸡", "爱意", "禁止", "狗", "亲亲", "叉", "礼物", "晕", "呆", "生病", "钻石", "拜", "怒", "示爱", "汗", "小鸡", "痛苦", "撇嘴", "惶恐", "口罩", "吐舌", "心碎", "生气", "可爱", "鬼脸", "跳舞", "男孩", "奸笑", "猪", "圈", "便便", "外星", "圣诞"]

我们先定义这四个参数分别为para1,para2,para3,para4。

再来看看window.asrsea是什么,window.asrsea=d,而d函数如下图所示

函数d传入四个参数,加密后返回,使用了另外三个函数a、b、c,它们又分别如下图所示,这里abcd参数和函数名称混淆,但我们只要抓住其本质,一个一个对应分析,就可以得出正确结果。

a函数生成16个随机字符,b函数是AES加密,模式为CBC,给定了初始向量'0102030405060708',c函数是RSA加密。

代码语言:javascript
复制
    # 生成16个随机字符,即a函数
    def _generate_random_strs(length):
        string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        # 控制次数参数i
        i = 0
        # 初始化随机字符串
        random_strs  = ""
        while i < length:
            e = random.random() * len(string)
            # 向下取整
            e = math.floor(e)
            random_strs = random_strs + list(string)[e]
            i = i + 1
        return random_strs


    # AES加密,即b函数
    def _AESencrypt(msg, key):
        # 如果不是16的倍数则进行填充(paddiing)     
        padding = 16 - len(msg) % 16
        msg = msg + padding * chr(padding)
        # 用来加密或者解密的初始向量(必须是16位)
        iv = '0102030405060708'

        cipher = AES.new(key, AES.MODE_CBC, iv)
        # 加密后得到的是bytes类型的数据
        encryptedbytes = cipher.encrypt(msg)
        # 使用Base64进行编码,返回byte字符串
        encodestrs = base64.b64encode(encryptedbytes)
        # 对byte字符串按utf-8进行解码
        enctext = encodestrs.decode('utf-8')
        return enctext


    # RSA加密,即c函数
    def _RSAencrypt(randomstrs, key, f):
        # 随机字符串逆序排列
        string = randomstrs[::-1]
        # 将随机字符串转换成byte类型数据
        text = bytes(string, 'utf-8')
        seckey = int(codecs.encode(text, encoding='hex'), 16)**int(key, 16) % int(f, 16)
        return format(seckey, 'x').zfill(256)

d函数中的encText调用了两次b函数,也就是两次AES加密,第一次参数为para1和para4,第二次参数为第一次加密后的结果和16位随机字符。

d函数中的encSecKey调用了c函数,参数是16为随机字符和para2,para3。

知道了整个加密的过程,我们来确定一下这四个参数的值。我们利用Fiddler进行js替换,在控制台打印出我们需要的四个参数就是para1,para2,para3,para4。首先下载网页上的js文件,并加入下面的代码,接着在Fiddler中选择替换js文件。

代码语言:javascript
复制
console.info(i3x);
console.info(bqu5z(["流泪", "强"]));
console.info(bqu5z(QE7x.md));
console.info(bqu5z(["爱心", "女孩", "惊恐", "大笑"]));
var bXY4c = window.asrsea(JSON.stringify(i3x), bqu5z(["流泪", "强"]), bqu5z(QE7x.md), bqu5z(["爱心", "女孩", "惊恐", "大笑"]));

刷新网页,可以发现控制台输出了相关的参数信息。这里很重要的一点,需要将网页缓存清除,删除之前的浏览记录。

在控制台上我们可以看到这四个参数分别是什么数据,后面三个参数为固定数值,而第一个参数是由userId,offset等构造而成的。

这样我们就可以得到这两个表单数据,用requests.post就可以轻松获得我们想要的信息。

本文的全部代码等所需文件已全部上传至后台,回复“网易云音乐”即可获得。

喜欢就点个赞吧❤

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法与数据之美 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档