网易云JS逆向分析

news/2024/9/20 2:33:17/文章来源:https://www.cnblogs.com/xiaoyus/p/18418650

网易云JS逆向分析

前言

本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与文章作者无关,若有侵权,请联系我立即删除!

阅读本篇文章,需要一定的爬虫基础,和js逆向思维,否则无法继续

首先找到一个歌单

image-20240904214816055

找到这个api接口

image-20240904185750624

api传参为这两个

image-20240904185839399

找到启动器

image-20240904190017126

发现这两个参数和刚刚api接口是一模一样的,那么大概率源码就在这里

image-20240904190134236

打断点,分析加密参数

image-20240904190337254

刷新页面,已经卡在这里了

image-20240904190425077

分析每个api参数

image-20240904190518973

X1x为后端api地址

i1x为csrf_token

e1x为请求方式,该值为post

我们的目标是抓取歌单评论信息,一直放行,直到这个接口

image-20240904190753973

分析这个参数,如下

image-20240904191316338

分析rid:A_PL_0_3865036,这后面的就是歌单id,threadId:A_PL_0_3865036,后面也是歌单id信息,后面的参数基本没用了,页面大小,偏移量和歌单属性

image-20240904191112608

那么就可以得到python代码向后端传的参数为这个

def get_data():id=3865036  # 歌单idurl = "https://music.163.com/weapi/comment/resource/comments/get"data = {'csrf_token': "","cursor": "-1",  # 0为精彩评论,-1为最新评论"offset": "0","orderType": "1","pageNo": "1","pageSize": "20","rid": f"A_PL_0_{id}","threadId": f"A_PL_0_{id}"}headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'}resp = requests.post(url, data=data, headers=headers)print(resp.text)

但是呢没有任何响应结果,说明参数加密了
image-20240904191651991

对比源参数即可看到,这些值都是乱码,显然是进行了加密的

image-20240904185839399

那么就要找js的加密节点,怎么找?回到这个界面

image-20240904192831183

把这段代码复制下来仔细分析

var bVi3x = window.asrsea(JSON.stringify(i1x), bse0x(["流泪", "强"]), bse0x(Qu1x.md), bse0x(["爱心", "女孩", "惊恐", "大笑"]));

分别对应如下值

image-20240904193330296

这里我们就得到了每个参数的值

使用变量进行替换

# 服务于函数d
g = "0CoJUm6Qyw8W8jud"   # bse0x(["爱心", "女孩", "惊恐", "大笑"])
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
e = "010001"    # bse0x(["流泪", "强"])

再放行,找到加密节点

image-20240904195300825

鼠标移动到这里,即可看到,使用了一个方法,方法名称叫 d

image-20240904195731888

即可看到这样一串代码

image-20240904195755290

贴上源码

!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")  // AES加密算法中需要的偏移量, 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
}();

仔细分析AES加密特征,打断点

image-20240904203114032

放行

image-20240904203339782

打印这些值

image-20240904203323650

此时即可得到参数 i ,如果你多次执行就会发现这个 i 值是变化的,调用的是a函数传了个16

image-20240904203509021

a 函数这就是一个随机计算结果,可以直接定死

image-20240904203516923

而 i 已经定死了,i = "2l8EuJuvLirixMmc" ,这里我执行了第二遍,就用我第二遍的 i 值,得到了已有的值

g = "0CoJUm6Qyw8W8jud"   # bse0x(["爱心", "女孩", "惊恐", "大笑"])
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
e = "010001"    # bse0x(["流泪", "强"])
i = "2l8EuJuvLirixMmc"  # 手动固定,函数中是随机的

偏移量之前已经在js代码的b函数找到了,这张图就可以很清楚的看到解密后的值就是 h.encText 的值

image-20240904204459458

image-20240904205241618

发现这个函数是RSA加密,我们已经得到了这个值,由上图可以看到,i 值为偏移量,e为 010001,f 未知,那么就先放一放

image-20240904205200570

image-20240904205735458

查看这个参数,断点

image-20240904210119630

记得放行查看值

image-20240904210638152

这样就能得到encSecKey的值,分析得到python逆向代码

def get_encSecKey():  # 由于i是固定的,所以经过c函数输出的encSecKey也是固定的return "288bca7fd6e42e24d4549f155b4eb6317ba323b914c9ee8aaccb786cabcd27773aea34d9413b8902f3a1a86e50863cec7e1f872092585cddd432951f210ae078e2f2c6b486c83c210820d5c09c73e2d3f225401ce1f5543f7a6f903c7bdc65b8ea27894c0299f52d801f05aaa6ec61e34082bec0135b9c74dabcabd1e1dba1ab"# 把参数进行加密,相当于
def get_params(data):  # 默认收到的是字符串first = enc_paramas(data, g)  # 第一次加密,再将第二次结果与i一起加密second = enc_paramas(first, i)  # 第二次加密return second  # 返回的就是paramas# 将数据长度转化为16的倍数, 为下面加密服务
def to_16(data):  # pad = 16 - len(data) % 16data += chr(pad) * padreturn datadef enc_paramas(data, key):    # 相当于js中的b(a, b)函数iv = "0102030405060708"  # AES加密算法中需要的偏移量data = to_16(data)aes = AES.new(key=key.encode('utf-8'), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)  # 创建加密器bs = aes.encrypt(data.encode('utf-8'))  # 加密,加密的长度必须是16的倍数,”123456789abcchr(4)chr(4)chr(4)chr(4)"return str(b64encode(bs), "utf-8")  # 转化成字符串

此时将刚刚没有任何结果的代码进行传参即可,半成品代码如下

import json
from base64 import b64encode
from Crypto.Cipher import AES  # pip install  pycryptodome
import requests# 设置好已知的值
g = "0CoJUm6Qyw8W8jud"   # bse0x(["爱心", "女孩", "惊恐", "大笑"])
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
e = "010001"    # bse0x(["流泪", "强"])
i = "2l8EuJuvLirixMmc"  # 手动固定,函数中是随机的def get_data():id=3865036  # 歌单idurl = "https://music.163.com/weapi/comment/resource/comments/get"data = {'csrf_token': "","cursor": "-1",  # 0为精彩评论,-1为最新评论"offset": "0","orderType": "1","pageNo": "1","pageSize": "20","rid": f"A_PL_0_{id}","threadId": f"A_PL_0_{id}"}headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'}resp = requests.post(url, data={"params": get_params(json.dumps(data)),  # 通过函数的加密得到服务器需要的params参数"encSecKey": get_encSecKey()}, headers=headers)print(resp.text)if __name__ == '__main__':get_data()

完整数据清洗后的代码

import random
import json
from base64 import b64encode
from Crypto.Cipher import AES  # pip install  pycryptodome
import requests# 服务于函数d
g = "0CoJUm6Qyw8W8jud"
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
e = "010001"
i = "2l8EuJuvLirixMmc"  # 手动固定,函数中是随机的def get_encSecKey():  # 由于i是固定的,所以经过c函数输出的encSecKey也是固定的return "288bca7fd6e42e24d4549f155b4eb6317ba323b914c9ee8aaccb786cabcd27773aea34d9413b8902f3a1a86e50863cec7e1f872092585cddd432951f210ae078e2f2c6b486c83c210820d5c09c73e2d3f225401ce1f5543f7a6f903c7bdc65b8ea27894c0299f52d801f05aaa6ec61e34082bec0135b9c74dabcabd1e1dba1ab"# 把参数进行加密
def get_params(data):  # 默认收到的是字符串first = enc_paramas(data, g)  # 第一次加密,再将第二次结果与i一起加密second = enc_paramas(first, i)  # 第二次加密return second  # 返回的就是paramas# 将数据长度转化为16的倍数, 为下面加密服务
def to_16(data):pad = 16 - len(data) % 16data += chr(pad) * padreturn datadef enc_paramas(data, key):iv = "0102030405060708"  # AES加密算法中需要的偏移量data = to_16(data)aes = AES.new(key=key.encode('utf-8'), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)  # 创建加密器bs = aes.encrypt(data.encode('utf-8'))  # 加密,加密的长度必须是16的倍数,”123456789abcchr(4)chr(4)chr(4)chr(4)"return str(b64encode(bs), "utf-8")  # 转化成字符串def get_data():id=3865036  # 歌单idurl = "https://music.163.com/weapi/comment/resource/comments/get"data = {'csrf_token': "","cursor": "-1",  # 0为精彩评论,-1为最新评论"offset": "0","orderType": "1","pageNo": "1","pageSize": "20","rid": f"A_PL_0_{id}","threadId": f"A_PL_0_{id}"}headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'}resp = requests.post(url, data={"params": get_params(json.dumps(data)),  # 通过函数的加密得到服务器需要的params参数"encSecKey": get_encSecKey()}, headers=headers)print(resp.text)dict = json.loads(resp.text)  # 将得到的内容转化为字典模式user_obj = dict['data']['hotComments']comment_data = []comment_sum = dict['data']['totalCount']if not user_obj:user_obj = dict['data']['comments']for _ in user_obj:content = _['content']nickname = _['user']['nickname']photo = _['user']['avatarUrl']timeStr = _['timeStr']like_count = _['likedCount']addres = _['ipLocation']['location']list = {'nickname': nickname,'content': content,'photo': photo,'timeStr': timeStr,'addres': addres,'like_count': like_count,'com_count': comment_sum}comment_data.append(list)print(comment_data)if __name__ == '__main__':get_data()

得到评论结果

image-20240904200835693

其他api接口也是如此,还可以搞一个扫码登录的,下面是我23年8月写的项目

项目推荐

这是我写的一个完整的爬虫django项目,集成了网易云扫码登录,歌单信息,歌曲/歌单评论,歌单收藏,歌曲播放等等运用了aiohttp异步爬虫,requests库,IP池,线程池,redis,中间件mysql数据库,等等等等项目仅供学习使用严禁商业用途!!!!记得点个关注,感谢

扫码登录

image-20240904182237838

网易云首页

image-20240904214654409

我的首页

image-20240904181934755

歌单列表

image-20240904182014204

源列表

image-20240904182045727

评论

image-20240904182030903

image-20240904201537098

歌曲播放效果

image-20240904201657253

。。。。。。。

总结

本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与文章作者无关,若有侵权,请联系我立即删除!,重要的事儿说三遍!!!

回忆往昔

111

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/799376.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机开启IPV6的建议

概述 默认情况vmware的nat网络模式是没有开启IPV6的,即便宿主机有IPV6。 开启方式:编辑---》选择vmnet8(NAT),点击NAT Settings(NAT设置),选择最下面的开启IPV6 NAT。 少侠,我看你气度不凡天赋异禀,骨骼精奇,这么帅,来了就帮推荐一把吧 我的最近更新 最新发布文章、框架、…

ZBlogPHP Leaked 1 hashtable iterators错误

当遇到 Z-Blog PHP 报告 “Leaked 1 hashtable iterators” 错误时,这通常表明内存泄漏或其他内存管理问题。这类错误通常出现在 PHP 内存管理或扩展中。以下是解决这一问题的一些常见步骤: 检查 PHP 配置问题描述:PHP 配置可能存在问题。 解决方法:编辑 php.ini 文件,确保…

Windows/Linux操作用户权限常用命令

环境:centos7.5(主要),win7 Linux/Centos(权限篇) 一、概述 Linux操作系统,设计用于支持多用户和处理多任务的服务器环境,实施了一套严密的权限控制系统。这一系统主要通过两个核心要素——用户身份和文件权限——来管理和限制对资源的访问。在Linux中,资源的访问权限…

Kali下安装与使用BeEF:反射型与存储型XSS攻击、Cookie会话劫持、键盘监听及浏览器操控技巧

早八人,护网在即,该学习了~前言 BEEFXSS(Browser Exploitation Framework XSS),更常见的称呼是BeEF(The Browser Exploitation Framework),是一个开源的浏览器漏洞利用框架。它由Michał Zalewski于2006年创建,旨在帮助渗透测试人员评估Web浏览器的安全性,发现并利用…

phpStudy 小皮 Windows面板 存在RCE漏洞

靶场资料后台自行领取【靶场】Phpstudy小皮面板存在RCE漏洞,通过分析和复现方式发现其实本质上是一个存储型XSS漏洞导致的RCE。通过系统登录用户名输入处的XSS配合系统后台自动添加计划任务实现RCE。这是登录成功的界面登录成功了就来和大佬们喝喝茶吧~首先在用户名登录的地方…

伪静态注入的总结

伪静态页面渗透 在日常的测试中,经常会遇到静态页面,尤其是政府类的站点(前提经过授权),此时就会非常的棘手,在下多试验后,发现以下思路或可以帮助我们跨越这个障碍。 伪静态即是网站本身是动态网页如.php、.asp、.aspx等格式动态网页有时这类动态网页还跟“?”加参数来…

文件上传10种waf绕过姿势

基础篇:https://mp.weixin.qq.com/s/od0djMG4iwO755N2YgDAHg 环境搭建 首先去官网下载安全狗,进行网站配置,或者后台回复【安全狗】,靶场源码和waf软件都准备好了,都是最新版本的,直接下载就行安全狗配置文件防护规则这里用upload-labs中的第六关进行文件上传测试第六关是…

什么是域?如何搭建?

域 域是计算机网络中的一个逻辑组织单元,具有安全边界,实现资源的集中管理和共享。它通常分为,单域 ,多域,父域,子域 ,域树(tree), 域森林(forest),DNS域名服务器。 单域和多域 单域指网络中所有计算机和用户隶属于同一域,便于集中管理;多域则将网络划分为多个独…

css布局之Grid布局

前言 最近了解到一种新的布局:grid布局(网格布局),grid并不是最近才看到的,以前在设置display的时候,会在属性值列表中看到,但却没有给过太多关注。一次偶然机会听到:对于九宫格布局的实现,grid布局会比flex布局实现起来更方便,作为flex深度使用者,这句话无疑引起了…

windows安装OpenSSL定义OPENSSL_MODULES

一、安装方式一: 1.1 下载和安装下载其他人做的便捷版安装包http://slproweb.com/products/Win32OpenSSL.html 1.2 配置环境变量:OPENSSL_HOME 1.3 配置环境变量:OPENSSL_MODULES

Ros2 - Moveit2 - 使用 Bullet 进行碰撞检查

除了灵活碰撞库 (FCL) 之外,Bullet 碰撞检测也可用作碰撞检查器。本教程以可视化碰撞教程为基础,展示碰撞。 此外,还提供连续碰撞检测(CCD),并通过 Bullet 进行演示。 入门 如果您还没有这样做,请确保您已经完成入门指南中的步骤。 运行代码 使用 Roslaunch 启动文件直接…

广播数据包报文格式

BLE报文由不同的域组成,如果域的长度超过一个字节,就涉及到先传输字节的低位还是高位的问题,这里分字节序和比特序: 字节序:大多数的多字节域都是从低字节开始传输。但是,并不是所有的多字节域都是从低字节开始传输。 比特序:各个字节传输时,每个字节都是从低位开始。前…