【WEB逆向】关于某音的算法研究

文章详细介绍了如何通过断点调试分析加密参数的生成流程,特别是XMLHttpRequest对象在远程调用中的作用。利用RPC模拟生成参数,并尝试在本地环境复现加密过程,涉及到对webmssdk.js的解混淆和环境模拟。最后提到了使用FastAPI实现接口的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

流程分析

远程调用

 fastapi实现接口


流程分析

逆向加密参数的第一步,分析流程。

通过堆栈信息点到源码中并断点。

apply方法能劫持另外一个对象的方法,继承另外一个对象的属性 apply方法接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function

断点之后,可知 t = this 是XMLHttpRequest对象,观察请求,当前请求对象的_url中包含了signature和x-bogus。

那么现在需要找到未带有signature和x-bogus的请求对象。

在e.nativeXMLHttpRequestSend 时往前调试7步左右,发现一处和XMLHttpRequest有关的方法。

在方法末尾的send处打上断点,然后放掉所有请求,重新触发断点。

此时可发现,在该断点的对象中,_url还未包含两个加密参数。

那么F11继续往下走,可见进入了混淆的webmssdk中,其对请求对象被赋予了某些操作。

当F8跳出这里回到最终的nativeXMLHttpRequestSend时,可发现_url中已经产生了两个签名。

只需要这两个断点即可分析大概的流程,既先构建一个XMLRequest对象,然后通过改写send方法将其交给webmssdk中的方法加密,加密之后再回到 XMLHttpRequest.prototype.send 中,重置send方法完成请求。

每个函数都有一个prototype属性,这个属性是指向一个原型对象,原型对象包含函数实例共享的方法和属性,
通俗来讲,当通过new来生成一个类的对象时,prototype对象的属性就会成为实例化对象的属性。

远程调用

目前已经知道参数是怎么来的,就可以通过RPC方法来模拟生成。

虽然我们还没有具体追到加密的JS中,没有看到加密方法,但是由于其加密过程的特殊性,是基于操作XMLRequest对象的方法来进行调用,所以我们可以复刻过程生成参数

本地的调用不要着急,先按步骤来学习。

RPC是指跨进程间的远程调用过程,此处的意思是本地操作浏览器执行一些JS方法并返回结果。

执行之后,查看控制台打印出的内容。

当我们在当前环境中发送一个请求,其返回的内容中包含了带有签名的链接,同时可看到 responseText中已经返回了数据,那么说明整体的加密和请求都包含在了send中。

所以将这部分代码在本地模拟,比如通过selenium操作chromderver在网站环境中发送请求,即可进行简单的采集。

(还有兴趣的继续往下阅读吧)

本地调用

上述分析中,已经明确了加密参数的生成流程,接下来需要处理webmssdk文件。

乐意花时间的可以尝试还原一下,或者慢慢调试下。

在线解混淆站点:cnlans.com:8887

我们需要在本地补上XMLReuqest,执行send方法,同时把webmssdk.js中的代码复制到本地运行。

先复制webmssdk.js运行,根据报错在开头补环境。

报错 Request is not defined,补:Request = function Request() {};

报错 Headers is not defined,补:Headers = function Headers() {};

报错 document is not defined,补:document = {}

报错 window is not defined,补:window = {}

报错document.addEventListener is not a function,补:document.addEventListener = function () {}

继续运行无报错,添加XMLReuqest代码并发送请求。

虽然代码运行了,但是一直没有结束,代码中有setInterval和setTimeout 定时执行着方法。

setTimeout = function(){return function(){}};
setInterval = function(){};

把定时器方法修改后,继续运行,发现没有报错也没有返回有用的结果。很正常,毕竟补的环境还都是 {}。

现在先把你所了解的、看到的环境信息都补上去。

比如 screen、navigator、document、location、canvas、localStorage、sessionStorage、PluginArray、Image等等。

结果补完之后还是啥都没有,此时就需要动手分析源码了。

在本地代码断点可以看出,req.send()走了一次就结束了,方法没走到webmssdk.js的代码中,说明我们的调用没有成功。

用我们第一段中的代码调试,打上断点。

执行代码看断点怎么走的,和我们本地执行不同的是,目前可直接进入function _0x65f4c7()。

那现在就需要对比本地和浏览器的区别在呢,像这类情况一般都是缺环境,或者是浏览器环境中有一些初始化的加载。

byted_acrawler是该页面独有的。(主要是最早的版本就需要byted_acrawler.init,所以一眼就看到了)

加上init之后,再次运行代码。

window.byted_acrawler.init({
    aid: 6383,
    boe: false,
    enablePathList:  ['/webcast/*', '/aweme/v1/', '/aweme/v2/*','/v1/message/send'],
    isSDK:false,
    region: "cn",
    v:false
});

报错:Cannot read properties of undefined (reading ‘onabort’)

定义:XMLHttpRequest.prototype.upload = function (){}

报错:Cannot read properties of undefined (reading ‘init’)

意思是window中未定义byted_acrawler,所以更没有init了。

所以可以猜这段代码中的byted_acrawler,没有附加到我们定义的window中,要么是缺环境,要么是补的window和源码的this不匹配。 那么加上window = this; 指向当前moudles

再次执行,成功返回结果。

分析结果

打印结果,发现req的onload中携带了send后加载的url,可发现经过两次计算,分别加上了X-Bogus和_signature。

本地能够成功调用之后,就可以着手还原这套调用流程,打上断点调试还原,这块笔者不写了。

本文主要是写教程,大概补了下图的就能生成值,但是不保证能请求成功。

补环境拿文字描述太过折磨,要补的东西毕竟多,一些简单的跳过了,各位自行尝试,珍重!

fastapi实现接口

涉及研究技术问题 觉得文章比较好就给我点个关注

本文只是技术探讨,如果对造成影响请告知,

<think>好的,用户想了解如何将抖webcast_uid转换为uid。首先,我需要回忆一下之前看到的引用内容。根据引用[1],提到通过抓包接口通常获取的是sec_uid,而sec_uid对应一个uid,所以需要转换。但用户问的是webcast_uid转uid,这可能涉及到不同的接口或方法。 接下来,我应该先理清抖中的各种ID类型。常见的ID包括UID(用户唯一标识)、sec_uid(安全相关的用户ID)、webcast_uid(可能用于直播间的ID)等。可能需要确认webcast_uid是否与sec_uid或UID有直接关联。 引用[1]提到sec_uid转uid的方法,或许webcast_uid也可以通过类似的方式转换。但需要明确的是,webcast_uid可能属于直播间或特定功能的标识,和用户UID可能不在同一个接口返回。因此,可能需要通过抓包分析相关接口,找到包含webcast_uid和UID的响应数据,从而建立对应关系。 另外,引用[2]提到使用公开的网页端接口,通过POST请求获取用户信息,包括UID。如果webcast_uid存在于这些接口的响应中,或许可以提取到对应的UID。但需要验证这些接口是否仍然有效,以及是否有权限访问。 可能的步骤包括:1. 使用抓包工具(如Charles或Fiddler)捕获抖客户端的网络请求,特别是涉及直播或用户信息的接口。2. 分析响应数据,查找webcast_uid和UID同时存在的字段。3. 构建相应的请求,传入webcast_uid,从响应中提取UID。 需要注意的是,抖的接口可能会频繁更新,方法可能失效。此外,未经授权的数据抓取可能违反平台政策,需遵守相关规定。 总结思路:通过抓包找到关联webcast_uid和UID的接口,解析响应数据获取对应关系,或利用现有公开接口进行转换。同时提醒用户注意接口变动和法律风险。</think>根据抖接口特性,webcast_uid与uid的转换可通过以下方式实现: 1. **接口抓包分析** 通过抓取抖直播间接口请求(如`webcast**`类接口),在响应数据中会同时存在webcast_uid与uid的映射关系。例如抓取到的数据包可能包含: ```json { "user_info": { "uid": "123456789", "webcast_uid": "987654321", "sec_uid": "MS4wLjABAAAA..." } } ``` 2. **调用公开接口** 抖网页端存在可获取用户信息的公开接口,例如: ```python import requests webcast_uid = "目标webcast_uid" api_url = "https://www.douyin.com/aweme/v1/web/user/profile/other/" params = { "device_platform": "webapp", "webcast_uid": webcast_uid } headers = { "Cookie": "抖登录cookie", "User-Agent": "Mozilla/5.0..." } response = requests.get(api_url, params=params, headers=headers) uid = response.json()['user']['uid'] ``` *注意:该方法需要有效cookie且存在风控限制[^1][^2]* 3. **sec_uid中间转换** 若无法直接获取映射关系,可先通过sec_uid进行转换: $$ webcast\_uid \xrightarrow{直播间接口} sec\_uid \xrightarrow{用户主页接口} uid $$ 此过程需解析两个接口的响应数据实现级联查询
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值