文章声明
本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与文章作者无关,若有侵权,请联系我立即删除!
概要
- 该篇文章是基于网易云音乐评论的分析
- (歌曲评论案例: 网易云音乐 搜索 蜃楼)
- 用到的工具 360浏览器
逆向目标
请求参数 params,encSecKey
开始整活
抓包
打开F12 选择XHR请求 定位到搜索数据包
参数定位及分析
-
直接搜索关键词,这里推荐搜索
encSecKey
因为这个词出现的地方大概率是加密的位置 -
搜索发现在很多js文件中都有该关键字,这个时候就要根据js文件名去猜测大概率是哪一个,大部分js文件名包含
core
的里面都会存在加密点(别问我怎么知道的,因为遇到过…哈哈哈) -
很幸运当前案例就是这样,进入
core.js
搜索encSecKey
, 把每个出现该关键词的位置都打上断点,然后进行网页操作触发评论请求,最终程序断到了这里
-
可以看到我们需要的两个加密参数(params, encSecKey)都在一起,而这两个参数都是由
bKL0x
对象下属性的值分别赋值的,再往上看,可以发现bKL0x
对象是由window.asrsea
函数的返回值得来的,我这里处理一下
var a = JSON.stringify(i1x)
var b = bvj1x(["流泪", "强"])
var c = bvj1x(Rj3x.md)
var d = bvj1x(["爱心", "女孩", "惊恐", "大笑"])
var bKL0x = window.asrsea(a, b, c, d)
-
想要得到
bKL0x
对象就必须先知道window.asrsea
这个函数的四个参数a,b,c,d都分别是什么,以及该函数内部到底是做了什么操作,接下来我们一个个解决 -
我们分别在控制台输出这几个参数
/*
大致分析一下各个参数后得到这样一个结论
参数 a 也就是 JSON.stringify(i1x)的构成,都是根据歌曲的id生成的,歌曲的不同得到的结果也不同
剩下三个参数(b,c,d) 我经过多次断点调试,在控制台输出发现每次运行的结果都是一致的,所以这三个参数是固定结果
下面分别做个记录
*/
a = xxx // 根据id而变化
b = '010001'
c = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
d = '0CoJUm6Qyw8W8jud'
-
关于
JSON.stringify
JSON.stringify 其实就等价于 Python中的 json.dumps
-
四个参数都大致了解了,接下里就要分析
window.asrsea
函数了, 进入函数并打断点,然后重新翻页发起评论请求,然后根据函数主体分析我们要研究哪些变量,函数的四个参数d,e,f,g分别对象上面分析的a,b,c,d四个参数
-
函数中用到的所有的已知数据无非就是传递的四个参数,而未知数据就只有
i以及h.encText
然后把encText当做参数传递给b函数才得到最终的encText -
解决
i
的生成,进入a方法,发现函数内部的操作其实就是返回长度为16位的随机字符串,并且我们还看到了关键词AES
字眼,但是并不知道和此次加密有无关联
-
还是老样子既然是随机值,那我们就固定这个值,不让他随机,那么这个
i数据
就解决了,解下来就看h.encText
的生成,第一个encText=b(d, g)
参数d,g我们都知道,然后进入b函数并打断点,很巧的是b方法就是上面截图中带有AES
字眼的函数,既然是AES那就好办了,知道key,iv,加密明文等就可以解决了
// 仔细看下这段代码,其实就是通用的js版AES加密模板
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()
}
/*
秘钥就是传递过来的第二个参数
iv 就是固定字符串 '0102030405060708'
加密模式为 CBC
明文就是传递过来的第一个参数
*/
在node中的实现就跟上面的代码差不多
- npm install crypto-js -g // 安装模块
- var CryptoJS = require("crypto-js") // 引入模块
function encdata(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()
}
console.log(encdata('参数1','参数2')) // 即可得到加密结果
-
找个在线网址测试一下 (https://tool.lmeee.com/jiami/aes), 测试后发现结果一致,加密没问题至此第一个encText就解决了,而第二个encText又是经过了一轮AES加密得到的结果,并且把第一个encText的值当做成加密的明文,i当做秘钥进行加密,继续在网站中测试
-
-
经过测试后发现加密结果都对得上,到这里第二个encText也就是请求参数
params
完美解决,然后再来看encSecKey
是如何生成的,进入c函数然后打断点,又发现一个关键词RSA
,猜测应该是标准的RSA加密
-
遇到 setMaxDigits, RSAKeyPair 这种使用node中的rsa加密库是无法解决的,我从网上找到了一大堆,终于找到了这种模板所依赖的代码,特此感谢一下这个朋友,我把链接贴在下面
网上找的资源: https://www.h5av.com/archives/250.html 我的阿里云盘资源: https://www.alipan.com/s/yfJozAUDvw2 我分享的只有一个js文件,集成了所需要的代码
-
既然有模板了,我们就来测试一下, 把c函数复制到我上面分享的阿里云盘的js文件中,在控制台分别查看几个参数对应的结果依次放到js文件中然后执行,可以发现加密结果是一致的
-
到此请求参数
encSecKey
也解决了,
总结
- params 经过了两次AES加密
- encSecKey 一次RSA加密
- encSecKey 所用到的加密参数和params所需要的加密参数是息息相关的