网易云音乐参数加密分析
找到加密函数
首先找到获取comments的url:https://music.163.com/weapi/comment/resource/comments/get?csrf_token=xxxxxxxxxxx
然后可以看到参数除了csrf_token都是加密过的,所以需要定位一下params
和encSecKey
如何被加密得到的。
分析是比较简单的,首先直接来一个xhr断点锁定weapi/comment/resource/comments/get
打好xhr断点之后,直接刷新页面
顺着调用栈开始找加密前的参数,可以一个栈一个栈跟着调试,也可以找可疑点,比如找params
和encSecKey
赋值的地方。
最后在u1x.be1x中找到了参数加密前的内容:
1 2 3 4 5 6 7
| { "cookie": true, "type": "json", "method": "GET", "data": "rid=R_SO_4_486188245&threadId=R_SO_4_486188245&pageNo=1&pageSize=20&cursor=-1&offset=0&orderType=1", "query": "rid=R_SO_4_486188245&threadId=R_SO_4_486188245&pageNo=1&pageSize=20&cursor=-1&offset=0&orderType=1" }
|
自然也可以找到参数加密的地方其实就是var bKL3x = window.asrsea(JSON.stringify(i1x), bvl3x(["流泪", "强"]), bvl3x(Rj6d.md), bvl3x(["爱心", "女孩", "惊恐", "大笑"]));
这里就可以看到加密的参数和secKey了,然后收集加密函数中的参数:bvl3x(["流泪", "强"])
是一个定值010001
,bvl3x(Rj6d.md)
也是一个定值00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7
,bvl3x(["爱心", "女孩", "惊恐", "大笑"])
也是一个定值0CoJUm6Qyw8W8jud
.
根据测试不同歌曲的rid
和threadId
都是R_SO_4_
+歌曲ID
抠JS代码
全局搜索window.asrsea
,就会找到函数的位置,将这个函数扣下来,然后可能会报错缺失某个函数,缺什么补什么,js代码实在太多这里就不贴了,抠js也很简单就是费点事件,也可以直接将这个js代码移植到本地,但是需要补环境。
最后写python脚本
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
| import json
import requests import execjs
headers = { 'accept': '*/*', 'accept-language': 'zh-CN,zh;q=0.9', 'content-type': 'application/x-www-form-urlencoded', 'priority': 'u=0, i', 'referer': 'https://music.163.com/playlist?id=922209928', 'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', }
def getparam(song_id, page_no, page_num, csrf_token): if csrf_token != "": return '{"rid":"R_SO_4_'+song_id+'","threadId":"R_SO_4_'+song_id+'","pageNo":"'+page_no+'","pageSize":"'+page_num+'","cursor":"-1","offset":"0","orderType":"1","csrf_token":"'+csrf_token+'"}' else: return '{"rid":"R_SO_4_'+song_id+'","threadId":"R_SO_4_'+song_id+'","pageNo":"'+page_no+'","pageSize":"'+page_num+'","cursor":"-1","offset":"0","orderType":"1"}'
def cryptoParam(data): with open("./cryptojs.js", "r", encoding='utf-8') as f: js_code = f.read() ctx = execjs.compile(js_code) param2 = '010001' param3 = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' param4 = '0CoJUm6Qyw8W8jud' result = ctx.call("lucifer.asrsea", data, param2, param3, param4) params = result.pop("encText") result['params'] = params return result
if __name__ == '__main__': url = "https://music.163.com/weapi/comment/resource/comments/get" song_id = '30431364' page_no = '1' page_num = '20' csrf_token = '' param = getparam(song_id,page_no,page_num,csrf_token) request_data = cryptoParam(param) response = requests.post(url=url,data=request_data,headers=headers) comments = json.loads(response.text)['data']['comments'] for i in comments: content = i['content'].replace("\n","") print(i['user']['nickname']+"---------------"+content)
|
然后看一下代码的运行效果,简单爬了一下某一首音乐的评论:
存在问题
在这里有一个问题,就是在请求参数中有一个pageSize
,根据测试这个pageSize是可以随意更改大小并返回对应数量的评论的,但是有一个问题就是请求时间特别长,如果批量发送这样的请求是不是会造成dos攻击,导致服务器瘫痪。
下载网易云歌曲
分析和上面的一样,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
| def downloadSong(ids): url = "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=" param = getDownloadParam(ids) request_data = cryptoParam(param) response = requests.post(url=url, data=request_data, headers=headers) song_info = json.loads(response.text) for i in song_info['data']: print(i['url'])
if __name__ == '__main__': downloadSong('1964850580')
|
经测试不可以下载vip歌曲,网易云音乐多处存在CSRF漏洞且未修复。