【Python爬虫---js逆向】Js逆向之网易云音乐
通过逆向找打这个加密window.asrsea这个函数了
首先明确这里的4个参数分别对应什么,分别对应着下面四个参数
JSON.stringify(i8a), bsF6z(["流泪", "强"]), bsF6z(St0x.md), bsF6z(["爱心", "女孩", "惊恐", "大笑"]
所以发现JSON.stringify (i8a)被b函数加工以后,再次被b函数进行加工,接下来到b函数里面看看是什么
终于发现了这是AES加密的特征
1,扣代码,对数据进行加密
接下来就是如何破解
第一种方法:直接全扣下来,缺什么就补什么
不知道如何加密的情况下,直接扣代码,缺什么就补什么(比较耗时,考验耐心,也比较好用)
打开pycharm,新建一个js文件
(注意了,你得安装好Node环境,pycharm写的js代码需要Node环境才能运行,而且浏览器环境跟Node环境有一些区别,我们从浏览器环境扣下来的js代码,在node环境运行的话会有些问题,根据具体问题补环境即可,比如说Node下js不能操作dom,没有window对象,如果扣下来的代码有window对象或者右操作dom的代码则需要进行适当的补环境)
所以自行百度准备好node环境
接下来可以扣代码了,思路就是缺什么函数,从浏览器复制什么函数,直到补完位置
比如说,就从加密入口函数下手
function d(d, e, f, g) {
var h = {}
, i = a(16);
return h.encText = b(d, g),
h.encText = b(h.encText, i),
h.encSecKey = c(i, e, f),
h
}
var first = '{"logs":"[{\\"action\\":\\"mobile_monitor\\",\\"json\\":{\\"meta._ver\\":2,\\"meta._dataName\\":\\"pip_lyric_monitor\\",\\"action\\":\\"render\\",\\"userAgent\\":\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36\\",\\"chromeVersion\\":116,\\"resourceId\\":1974443814,\\"resourceType\\":\\"song\\"}}]","csrf_token":""}'
var second = '010001'
var third = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
var forth = '0CoJUm6Qyw8W8jud'
var result = d(first,second,third,forth)
console.log(result)
加密函数是d,d需要四个参数,之前讲过了,分别是
JSON.stringify(i8a), bsF6z(["流泪", "强"]), bsF6z(St0x.md), bsF6z(["爱心", "女孩", "惊恐", "大笑"]
分别在console里面输出一下可以拿到一个他的值(而且不是随机的,是固定的)
需要注意的是第一个参数,JSON.stringify这个函数 用于把一个对象序列化,简单理解就是变成字符串,如有个对象{"name":"aini","age":18},序列化以后就成了'{"name":"aini","age":18}',整体用单引号包裹,变成了字符串(可以自己百度一下JS序列化反序列相关知识
接下来就是执行函数。缺什么补什么,直到成功为止
(注意运行js代码需要Node环境,请提前下载安装好,还有就是在终端cd 到你当前目录再运行)
b函数没找到,缺什么就补什么
就这样缺什么就补什么,通过九九八十一难,终于所有加密代码都扣完了、
注意:有些需要补的函数直接全局搜即可,找起来比较快,比如现在提示缺digitToHex函数,那直接复制去浏览区全局搜,步骤如下
就这样很容易的找到函数了
第二中方法,用第三方库扣代码
首先我们需要安装第三方库 crypto-js
可以用包管理软件npm ,如果你下载安装好了node环境而且配置好了环境变量npm可以直接使用的
先检车是否有npm
打开终端以后 输入 npm -v 如果看到版本说明安装好了,如果报错请百度一下,如何安装node和npm
npm install crypto-js 提示升级一下npm版本,那就先进行升级
我之前安装过这个包,所以我不安装了,我直接给大伙上代码
首先需要引入我们安装的crypto-js包
node环境中用 requere函数
还有从一个Rsa加密文件里分别取出三个函数(这个文件内容很长,就不放这里了,有需要的留言)
我们注意带!function里面是一个立即执行函数,里面还有a,b,c,d四个函数,只要我们进行适当替换,就可以不用扣第一种方法一样扣大量代码了
const CryptoJS = require("crypto-js")
var window = this
const {
setMaxDigits,
RSAKeyPair,
encryptedString
} = require("./Ras加密");
!function() {
function a(a) {
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d += 1)
e = Math.random() * b.length,
e = Math.floor(e),
c += b.charAt(e);
return c
}
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse("0102030405060708")
, e = CryptoJS.enc.Utf8.parse(a)
, f = CryptoJS.AES.encrypt(e, c, {
iv: d,
mode: CryptoJS.mode.CBC
});
return f.toString()
}
function c(a, b, c) {
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
function d(d, e, f, g) {
var h = {}
, i = a(16);
return h.encText = b(d, g),
h.encText = b(h.encText, i),
h.encSecKey = c(i, e, f),
h
}
function e(a, b, d, e) {
var f = {};
return f.encText = c(a + e, b, d),
f
}
window.asrsea = d,
window.ecnonasr = e
}();
var params = {
csrf_token: "",
encodeType: "aac",
ids: "[1325905146]",
level: "standard"
}
var second = '010001'
var third = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
var forth = '0CoJUm6Qyw8W8jud'
function fn(params) {
return window.asrsea(JSON.stringify(params),second,third,forth)
}
function c(a,b,c){
var d,e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d,a)
}
这是一个立即执行函数,里面是a,b,c,d四个函数,主要加密逻辑就在其中,我们已经导入了crypto-js包,还有从RSA加密里面导入了三个函数这个解密文件就写完了
需要注意的是var windows = this
因为我们扣的代码里有window,而node里没有window ,所以需要补window环境
2,接下来就是用Python写代码进项爬取音乐
import requests
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')
import execjs
url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='
f = open('用第三方库扣代码.js',mode='r',encoding="utf-8")
js_code = f.read()
params = {
'csrf_token': "",
'encodeType': "aac",
'ids': "[1325905146,2025152494]",
'level': "standard"
}
js = execjs.compile(js_code)
res = js.call("fn",params)
data = {
'params': res['encText'],
'encSecKey': res['encSecKey']
}
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
session = requests.Session()
session.headers = headers
res = session.post(url=url,data=data)
dic = res.json()
items = dic['data']
for i in items:
print(i['url'])
这是Python代码,我们直接读取第三方库扣代码文件里的代码,执行,拿到加密结果以后既可以发请求,获取到URL音乐URL了
接下来就是再往这个URL发请求,直接拿到相应结果以后,以二进制形式写入到文件就可以了
由于能分享的内容有限,详细逆向过程被迫删掉了,想了解的可以技术交流一下
好了今天就讲到这里,如果遇到问题,或者不懂的地方可以留言,我会及时回复的