您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > javascript

玩转 JS 逆向:RPC 加持,爬虫效率飙升

时间:2023-08-17 14:57:33  来源:  作者:博学多才的叶慢慢

来源: AIrPython/ target=_blank class=infotextkey>Python

作者:星安果

一些复杂的网站针对参数是层层加密,如果选择硬刚,去扣代码、补环境,耗时耗力的同时,不一定能获取完整的加密逻辑

在 JS 逆向中,我们可以通过 RPC 通信,直接调用浏览器的方法生成加密参数,这样可以省去扣代码的时间

本篇文章将介绍 Sekiro RPC 进行 JS 逆向的完整流程

目标网站:

aHR0cHM6Ly93d3cueGluZ3R1LmNuL3N1cC9jcmVhdG9yL2hvdA==

具体操作步骤如下:

1、Sekiro RPC

Sekiro 是一个多语言的、分布式网络拓扑无关的服务发布平台

它能基于长连接和代码注入 API 服务暴露的框架,可用于逆向(包含 JS 逆向和 App 逆向)

官网:

https://sekiro.iinti.cn/sekiro-doc/

2、分析网站

打开目标网站,发现接口 /h/api/gateway/handler_get 中的查询参数 sign 是加密的

 

在 Sources - Page 面板下,通过关键字 sign: 全局查询

发现加密参数生成的具体逻辑如下:

PS:通过方法 generatePayload 生成 sign,其中 c、l 为参数

文件位置:

https://*/obj/goofy/star/idou_fe/assets/vendor-a1b40867.js

 

然后,在方法 generatePayload 方法内添加条件断点

这样,通过多次 Debugger 分析,可以得出参数的生成规则(即:参数固定值、参数生成逻辑)

//条件监听
//条件:c.service_name==='author.AdStarAuthorService'

这样,在调试模式下,我们可以在浏览器控制台进行测试了

如下,直接调用方法可以拿到加密后的参数

 

3、加密文件重写 Overrides

在本地新建一个文件夹,Sources - Overrides 关联该本地目录

PS:开启 Overrides 并授予权限

在 Sources - Page 面板下,选择 vendor-a1b40867.js 文件右键,选择 Save for overrides 将文件保存到 Overrides 中

4、Sekiro 定义

修改 Overrides 中 vendor-a1b40867.js 文件

定义 SekiroClient 方法对象并实例化,注册一个方法进行监听处理

SekiroClient 源码如下:

https://raw.Githubusercontent.com/yint-tech/sekiro-samples/main/demo-web/sekiroWeb.js

通过关键字 generatePayload 找到对应方法,回车换行,输入如下逻辑

PS:修改源码后,需要重新开启、关闭 Overrides 开关一次( Enable Local Overrides )

...
function SekiroClient(e){if(this.wsURL=e,this.handlers={},this.socket={},!e)throw new Error("wsURL can not be empty!!");this.webSocketFactory=this.resolveWebSocketFactory(),this.connect()}SekiroClient.prototype.resolveWebSocketFactory=function(){if("object"==typeof window){var e=window.WebSocket?window.WebSocket:window.MozWebSocket;return function(o){function t(o){this.mSocket=new e(o)}return t.prototype.close=function(){this.mSocket.close()},t.prototype.onmessage=function(e){this.mSocket.onmessage=e},t.prototype.onopen=function(e){this.mSocket.onopen=e},t.prototype.onclose=function(e){this.mSocket.onclose=e},t.prototype.send=function(e){this.mSocket.send(e)},new t(o)}}if("object"==typeof weex)try{console.log("test webSocket for weex");var o=weex.requireModule("webSocket");return console.log("find webSocket for weex:"+o),function(e){try{o.close()}catch(e){}return o.WebSocket(e,""),o}}catch(e){console.log(e)}if("object"==typeof WebSocket)return function(o){return new e(o)};throw new Error("the js environment do not support websocket")},SekiroClient.prototype.connect=function(){console.log("sekiro: begin of connect to wsURL: "+this.wsURL);var e=this;try{this.socket=this.webSocketFactory(this.wsURL)}catch(o){return console.log("sekiro: create connection failed,reconnect after 2s:"+o),void setTimeout(function(){e.connect()},2e3)}this.socket.onmessage(function(o){e.handleSekiroRequest(o.data)}),this.socket.onopen(function(e){console.log("sekiro: open a sekiro client connection")}),this.socket.onclose(function(o){console.log("sekiro: disconnected ,reconnection after 2s"),setTimeout(function(){e.connect()},2e3)})},SekiroClient.prototype.handleSekiroRequest=function(e){console.log("receive sekiro request: "+e);var o=JSON.parse(e),t=o.__sekiro_seq__;if(o.action){var n=o.action;if(this.handlers[n]){var s=this.handlers[n],i=this;try{s(o,function(e){try{i.sendSuccess(t,e)}catch(e){i.sendFailed(t,"e:"+e)}},function(e){i.sendFailed(t,e)})}catch(e){console.log("error: "+e),i.sendFailed(t,":"+e)}}else this.sendFailed(t,"no action handler: "+n+" defined")}else this.sendFailed(t,"need request param {action}")},SekiroClient.prototype.sendSuccess=function(e,o){var t;if("string"==typeof o)try{t=JSON.parse(o)}catch(e){(t={}).data=o}else"object"==typeof o?t=o:(t={}).data=o;(Array.isArray(t)||"string"==typeof t)&&(t={data:t,code:0}),t.code?t.code=0:(t.status,t.status=0),t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("response :"+n),this.socket.send(n)},SekiroClient.prototype.sendFailed=function(e,o){"string"!=typeof o&&(o=JSON.stringify(o));var t={};t.message=o,t.status=-1,t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("sekiro: response :"+n),this.socket.send(n)},SekiroClient.prototype.registerAction=function(e,o){if("string"!=typeof e)throw new Error("an action must be string");if("function"!=typeof o)throw new Error("a handler must be function");return console.log("sekiro: register action: "+e),this.handlers[e]=o,this};
//实例化一个客户端连接对象
//group:业务类型
//clientId:设备id
var client = new SekiroClient("wss://sekiro.iinti.cn:5612/business/register?group=test_web&clientId=" + Math.random());
//注册
client.registerAction("xingtu", function (request, resolve, reject) {
// var enc_data = request['data']
// var res = enc_data;
// resolve(v()(res));
let c={
"hot_list_id": "0",
"tag": "61e541324fe6649d1b8a2ee3",
"service_name": "author.AdStarAuthorService",
"service_method": "GetHotListData"
};
let l={
"strict": true,
"serializing": true,
"rule": {
"include": [
"hot_list_id",
"tag",
"download",
"image_download",
"province",
"city",
"rlid"
]
}
};
resolve(generatePayload(c,l));
});
...

重新访问下面地址,查看控制台,发现 Sekiro 已经准备完毕

 

5、Python 调用

通过 Websocket 调用,借助浏览器调用 generatePayload() 方法,获取加密后的值 sign

最后,组成完整的 URL 获取数据

import requests
# Websocket通讯,获取sign(Sekiro)
def get_signature():
data = {"group": "test_web",
"action": "xingtu"
}
resp = requests.get("http://sekiro.iinti.cn:5612/business/invoke", params=data).json()
return resp['sign']
# 获取数据
def get_data(sign):
url = f"https://*host/h/api/gateway/handler_get/?hot_list_id=0&tag=*tag&service_name=author.AdStarAuthorService&service_method=GetHotListData&sign_strict=1&sign={sign}"
payload = {}
headers = {
'authority': '*host',
'agw-js-conv': 'str',
'pragma': 'no-cache',
'x-login-source': '1',
'x-star-service-method': 'GetHotListData',
'x-star-service-name': 'author.AdStarAuthorService',
'Cookie': 'cookie',
'User-Agent': 'Mozilla/5.0 (macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/115.0.0.0 Safari/537.36'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
if __name__ == '__main__':
sign = get_signature()
print("sign:",sign)
get_data(sign)

6、补充一下

除了 Overrides 覆盖文件外,还可以使用油猴脚本或浏览器插件进行脚本注入,完成 Sekiro 的初始化及事件注册

相比传统的 JS 逆向,利用 Sekiro 直接调用方法获取加密参数更加方便快捷然后;但是它有一个缺点,即:需要通过浏览器打开目标网站



Tags:JS   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
又出新JS运行时了!JS运行时大盘点
Node.js是基于Google V8引擎的JavaScript运行时,以非阻塞I/O和事件驱动架构为特色,实现全栈开发。它跨平台且拥有丰富的生态系统,但也面临安全性、TypeScript支持和性能等挑战...【详细内容】
2024-03-21  Search: JS  点击:(23)  评论:(0)  加入收藏
GitHub顶流"Web OS"——运行于浏览器的桌面操作系统、用户超100万、原生jQuery和JS编写
Puter 是近日在 GitHub 上最受欢迎的一款开源项目,正式开源还没到一周 ——star 数就已接近 7k。作者表示这个项目已开发 3 年,并获得了超过 100 万用户。根据介绍,P...【详细内容】
2024-03-10  Search: JS  点击:(17)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown —— 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  Search: JS  点击:(11)  评论:(0)  加入收藏
如何在Rust中操作JSON,你学会了吗?
sonic-rs ​还具有一些额外的方法来进行惰性评估和提高速度。例如,如果我们想要一个 JSON​ 字符串文字,我们可以在反序列化时使用 LazyValue​ 类型将其转换为一个仍然带有斜...【详细内容】
2024-02-27  Search: JS  点击:(47)  评论:(0)  加入收藏
JS小知识,使用这6个小技巧,避免过多的使用 if 语句
最近在重构我的代码时,我注意到早期的代码使用了太多的 if 语句,达到了我以前从未见过的程度。这就是为什么我认为分享这些可以帮助我们避免使用过多 if 语句的简单技巧很重要...【详细内容】
2024-01-30  Search: JS  点击:(56)  评论:(0)  加入收藏
花 15 分钟把 Express.js 搞明白,全栈没有那么难
Express 是老牌的 Node.js 框架,以简单和轻量著称,几行代码就可以启动一个 HTTP 服务器。市面上主流的 Node.js 框架,如 Egg.js、Nest.js 等都与 Express 息息相关。Express 框...【详细内容】
2024-01-16  Search: JS  点击:(86)  评论:(0)  加入收藏
JS 中如何克隆对象?你学会了吗?
大家好,这里是大家的林语冰。JS 中如何克隆对象?此问题看似简单,实际十分复杂。假设我们需要获取下述对象的拷贝。const cat = { name: '薛定谔', girlFriends: { na...【详细内容】
2024-01-05  Search: JS  点击:(102)  评论:(0)  加入收藏
理解 Node.js 中的事件循环
你已经使用 Node.js 一段时间了,构建了一些应用程序,尝试了不同的模块,甚至对异步编程感到很舒适。但是有些事情一直在困扰着你——事件循环(Event Loop)。如果你像我...【详细内容】
2024-01-05  Search: JS  点击:(111)  评论:(0)  加入收藏
彻底搞懂 JS 类型转换
1. 什么是类型转换?Javascript 是一种弱类型语言,这意味着变量是没有明确类型的,而是由 JavaScript 引擎在编译时隐式完成。类型转换就是将一种数据类型转换为另一种数据类型,例...【详细内容】
2024-01-03  Search: JS  点击:(104)  评论:(0)  加入收藏
.NET配置文件大揭秘:轻松读取JSON、XML、INI和环境变量
概述:.NET中的IConfiguration接口提供了一种多源读取配置信息的灵活机制,包括JSON、XML、INI文件和环境变量。通过示例,清晰演示了从这些不同源中读取配置的方法,使配置获取变得...【详细内容】
2023-12-28  Search: JS  点击:(92)  评论:(0)  加入收藏
▌简易百科推荐
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  前端新世界  微信公众号  Tags:JavaScript   点击:(4)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践——如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  前端新世界  微信公众号  Tags:JavaScript   点击:(25)  评论:(0)  加入收藏
又出新JS运行时了!JS运行时大盘点
Node.js是基于Google V8引擎的JavaScript运行时,以非阻塞I/O和事件驱动架构为特色,实现全栈开发。它跨平台且拥有丰富的生态系统,但也面临安全性、TypeScript支持和性能等挑战...【详细内容】
2024-03-21  前端充电宝  微信公众号  Tags:JS   点击:(23)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  前端历险记  微信公众号  Tags:JavaScript   点击:(20)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  WangLiwen    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  京东云开发者    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06    51CTO  Tags:JavaScript   点击:(52)  评论:(0)  加入收藏
JS小知识,使用这6个小技巧,避免过多的使用 if 语句
最近在重构我的代码时,我注意到早期的代码使用了太多的 if 语句,达到了我以前从未见过的程度。这就是为什么我认为分享这些可以帮助我们避免使用过多 if 语句的简单技巧很重要...【详细内容】
2024-01-30  前端达人  今日头条  Tags:JS   点击:(56)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  南城大前端  微信公众号  Tags:JavaScript   点击:(65)  评论:(0)  加入收藏
使用 JavaScript 清理我的 200GB iCloud,有了一个意外发现!
本文作者在综合成本因素之下,决定用 Java 脚本来清理一下自己的 iCloud,结果却有了一个意外发现,即在 iCloud 中上传同一个视频和删除此视频之后,iCloud 的空间并不一致,这到底是...【详细内容】
2024-01-11    CSDN  Tags:JavaScript   点击:(97)  评论:(0)  加入收藏
站内最新
站内热门
站内头条