js逆向实战之酷我音乐请求参数reqId加密逻辑

news/2024/12/23 21:06:25/文章来源:https://www.cnblogs.com/sbhglqy/p/18443120

声明:本篇文章仅用于知识分享

实战网站:https://www.kuwo.cn/search/list?key=可以不是你

加密逻辑分析

  1. 访问界面,根据数据包的回显内容判断哪个是我们需要的。
    image

  2. 找到相应的数据包,看下请求参数。
    image
    发现reqId参数是一串随机字符串,所以就需要知道该参数的生成过程。

  3. 全局搜索reqId,总共有9个结果。
    image
    下面5个是固定值不需要看,上面四个无法判断,所以都得打上断点。

  4. 刷新界面,看触发哪一个。
    image
    执行到对应处的时候,n已经生成了特定格式的字符串,说明加密逻辑在上面。

  5. 往上找n的生成过程
    image
    关键语句:n = l()()

  6. 控制台输出l()的结果,找到函数的定位处。
    image
    image

  7. n=l()()处打上断点,在函数第一行打上断点,重新刷新界面让程序运行到这里。
    image

  8. 记住传进来的三个参数都为undefined,让程序一步一步往下执行。前面四行的变量值都为固定值,如下。
    image
    继续往下进入if判断,m是个数组,其由l()生成。
    image
    由于我们不能判断其是个固定值还是随机值,可以在控制台多输出几遍。
    image
    每次结果都不一样,说明是个随机值,等下在抠代码的时候,我们可以给m变量随便赋值即可。再往下,会通过运算得到fv的值。
    image
    接下来分析var y = void 0 !== e.msecs ? e.msecs : (new Date).getTime(),是个三目运算,void 0 !== e.msecs的值为false,所以简化一下就是var y = (new Date).getTime()
    image
    w = void 0 !== e.nsecs ? e.nsecs : h + 1分析逻辑与上面一致,void 0 !== e.nsecs的值为false,所以简化一下就是var w = h + 1
    image
    下面的代码就全是一系列的运算操作了,就暂时先不分析了。
    image
    直接运行到return t || c(b)处,分别看下tc(b)的输出。
    image
    发现c(b)才是我们需要的输出,看下b是什么。
    image
    就是一个数组,说明加密逻辑就是c()函数了。控制台输出c,找到它的定位处。
    image
    打断点进来。
    image
    e是我们传进来的数组,t的值为undefined。继续往下执行,看下ir的值是什么。
    image
    i是0,rn赋值给它的,找n的生成过程,往上翻几眼就能找到。
    image
    通过循环得到,直接复制代码即可。至此,大概的加密逻辑都分析到位了。

  9. 抠代码的时候先把能简化的简化,如果碰到有变量未定义,在该行代码的上下行找找就能找到。
    好像就下面两个变量。
    image
    完整的js如下。

function generate(e, t, n) {var i = t && n || 0, r, o, h=0,d=0, b = t || [], f = undefined, v = undefined;if (null == f || null == v) {var m = {"0": 43,"1": 64,"2": 160,"3": 14,"4": 221,"5": 55,"6": 249,"7": 97,"8": 86,"9": 170,"10": 120,"11": 218,"12": 66,"13": 188,"14": 238,"15": 102};null == f && (f = r = [1 | m[0], m[1], m[2], m[3], m[4], m[5]]),null == v && (v = o = 16383 & (m[6] << 8 | m[7]))}var y = (new Date).getTime(), w = h + 1, dt = y - d + (w - h) / 1e4;if (dt < 0 && void 0 === undefined && (v = v + 1 & 16383),(dt < 0 || y > d) && void 0 === undefined && (w = 0),w >= 1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");d = y,h = w,o = v;var A = (1e4 * (268435455 & (y += 122192928e5)) + w) % 4294967296;b[i++] = A >>> 24 & 255,b[i++] = A >>> 16 & 255,b[i++] = A >>> 8 & 255,b[i++] = 255 & A;var x = y / 4294967296 * 1e4 & 268435455;b[i++] = x >>> 8 & 255,b[i++] = 255 & x,b[i++] = x >>> 24 & 15 | 16,b[i++] = x >>> 16 & 255,b[i++] = v >>> 8 | 128,b[i++] = 255 & v;for (var T = 0; T < 6; ++T)b[i + T] = f[T];return t || c(b)
}function c(e, t) {for (var n = [], i = 0; i < 256; ++i)n[i] = (i + 256).toString(16).substr(1);var i = t || 0, r = n;return [r[e[i++]], r[e[i++]], r[e[i++]], r[e[i++]], "-", r[e[i++]], r[e[i++]], "-", r[e[i++]], r[e[i++]], "-", r[e[i++]], r[e[i++]], "-", r[e[i++]], r[e[i++]], r[e[i++]], r[e[i++]], r[e[i++]], r[e[i++]]].join("")
}// console.log(generate());

运行结果如下,符合我们的预期,每次运行的结果都不一样。
image

  1. 最后编写python代码获取数据即可。
import requests
import execjsfile = open("test.js", mode="r")
exec_code = file.read()
exec_js = execjs.compile(exec_code)
reqId = exec_js.call("generate")key = input("请输入你要查询的音乐:")url = "https://www.kuwo.cn/openapi/v1/www/search/searchKey?key={}" \"&httpsStatus=1&reqId={}&plat=web_www&from=".format(key, reqId)
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/129.0.0.0 Safari/537.36"}
resp = requests.get(url, headers=headers)
resp.encoding = "utf-8"
print(resp.content.decode("utf-8"))

运行结果如下。
image
跟页面回显的内容一致。
image
大功告成,结束收工。

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

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

相关文章

14_初步解析document的核心元数据以及图解剖析index创建反例

1、_index元数据 2、_type元数据 3、_id元数据 { "_index": "test_index", "_type": "test_type", "_id": "1", "_version": 1, "found": true, "_source": { "test_content&…

15_document id的手动指定与自动生成两种方式解析

1、手动指定document id 2、自动生成document id1、手动指定document id (1)根据应用情况来说,是否满足手动指定document id的前提: 一般来说,是从某些其他的系统中,导入一些数据到es时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为es中document的id。举个例…

13_图解Elasticsearch容错机制:master选举,replica容错,数据恢复

课程大纲 1、图解Elasticsearch容错机制:master选举,replica容错,数据恢复 (1)9 shard,3 node (2)master node宕机,自动master选举,red (3)replica容错:新master将replica提升为primary shard,yellow (4)重启宕机node,master copy replica到该node,使用原有的…

12_分布式原理_图解横向扩容过程,如何超出扩容极限,以及如何提升容错性

1、图解横向扩容过程,如何超出扩容极限,以及如何提升容错性 (1)primary&replica自动负载均衡,6个shard,3 primary,3 replica (2)每个node有更少的shard,IO/CPU/Memory资源给每个shard分配更多,每个shard性能更好 (3)扩容的极限,6个shard(3 primary,3 repli…

09_手工画图剖析Elasticsearch的基础分布式架构

课程大纲 1、Elasticsearch对复杂分布式机制的透明隐藏特性 2、Elasticsearch的垂直扩容与水平扩容 3、增减或减少节点时的数据rebalance 4、master节点 5、节点对等的分布式架构1、Elasticsearch对复杂分布式机制的透明隐藏特性 Elasticsearch是一套分布式的系统,分布式是为了…

10_shardreplica机制再次梳理以及单node环境中创建index图解

1、shard&replica机制再次梳理 2、图解单node环境下创建index是什么样子的1、shard&replica机制再次梳理 (1)index包含多个shard (2)每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力 (3)增减节点时,shard会自动在nod…

04_手工画图剖析Elasticsearch核心概念:NRT、索引、分片、副本等

课程大纲 1、lucene和elasticsearch的前世今生 2、elasticsearch的核心概念 3、elasticsearch核心概念 vs. 数据库核心概念1、lucene和elasticsearch的前世今生 lucene,最先进、功能最强大的搜索库,直接基于lucene开发,非常复杂,api复杂(实现一些简单的功能,写大量的java…

02_用大白话告诉你什么是Elasticsearch

大白话、什么是Elasticsearch Elasticsearch,分布式,高性能,高可用,可伸缩的搜索和分析系统 1、什么是搜索? 2、如果用数据库做搜索会怎么样? 3、什么是全文检索、倒排索引和Lucene? 4、什么是Elasticsearch?1、什么是搜索? 百度:我们比如说想找寻任何的信息的时候,…

25个单据看透支付

本文深入解析了25个关键单据在支付环节中的核心作用与重要性。这些单据涵盖了支付指令、收款确认、交易凭证等多个方面,是支付流程中不可或缺的组成部分。文章通过详细剖析每个单据的功能、使用场景及合规要求,为读者提供了一套全面的支付单据知识体系。此外,文章还探讨了单…

吴恩达大模型教程笔记-七-

吴恩达大模型教程笔记(七) LangChain_微调ChatGPT提示词_RAG模型应用_agent_生成式AI - P29:5——基于文档的问答 - 吴恩达大模型 - BV1gLeueWE5N人们构建的最常见复杂应用之一。使用llm是一个可回答文档内或关于文档问题的系统,给定一段文本可能来自PDF文件或网页,或公司…

吴恩达大模型教程笔记-六-

吴恩达大模型教程笔记(六) LangChain_微调ChatGPT提示词_RAG模型应用_agent_生成式AI - P21:3. 第二篇 - RAG 指标三元组(RAG Triad of metrics) 中英文字幕 - 吴恩达大模型 - BV1gLeueWE5N本节课我们将深入探讨评估,我们将带你了解如何评估服务器架设的核心概念,具体来说…

吴恩达大模型教程笔记-二-

吴恩达大模型教程笔记(二) 【LangChain大模型应用开发】DeepLearning.AI - P4:4——链 - 吴恩达大模型 - BV1iZ421M79T这节课,这节课。哈里森将教授土地链最重要的基础构建块,哈里森将教授土地链最重要的基础构建块,即链条,即链条,链条通常结合一个大语言模型和一个提示…