抖音直播wss链接 signature 分析(水一贴)

已经有大半年没有水帖子了,是真的没时间啊

今天水一下抖音web端的直播wss的 signature 参数,这玩意出来,貌似是几个月之前的事情了,搞完之后一直也没时间记录。


打开网页可以看到如下信息。

抖音直播wss链接 signature 分析(水一贴)_第1张图片

查看请求调用堆栈,非常短
抖音直播wss链接 signature 分析(水一贴)_第2张图片

从这个地方进去

抖音直播wss链接 signature 分析(水一贴)_第3张图片

那么你就会进到这个位置

抖音直播wss链接 signature 分析(水一贴)_第4张图片
下断点,然后重新刷心,会在此处断下,断下之后,单步进入到函数内部,然后,在return的地方打上断点

抖音直播wss链接 signature 分析(水一贴)_第5张图片

然后你就会看到他是从这个地方计算出来的

抖音直播wss链接 signature 分析(水一贴)_第6张图片

知道了出处,知道了位置,下面就是分析他的计算过程


c变量接的是一个函数,函数传了2个参数,一个是u,一个是s


c = ((t, e = []) => {
	var r, n, o;
	let i = "";
	for (const {
		param_name: u
	} of e)
		i += `,${u}=${null != (r = t[u]) ? r : ""}`;
	const s = {
		"X-MS-STUB": D()(i.substring(1))
	};
	let a = {};
	return window.byted_acrawler && (a = null == (n = null == window ? void 0 : window.byted_acrawler) ? void 0 : n.frontierSign(s)), {
		signature: null != (o = a["X-Bogus"]) ? o : ""
	}
})(u, s);

u的内容是这样的,一些基本信息。
抖音直播wss链接 signature 分析(水一贴)_第7张图片

s是一个写死的数组

抖音直播wss链接 signature 分析(水一贴)_第8张图片

到了这一步之后,继续往下走,分析代码会发现,这里有个函数
抖音直播wss链接 signature 分析(水一贴)_第9张图片

D()(i.substring(1)) 中,像这种调用,就不要去跟D函数了,直接进到 D() 里面,进到函数里面就是下面这样,在return处下断点

抖音直播wss链接 signature 分析(水一贴)_第10张图片
首先看下这个

var n = r.wordsToBytes(s(e, t));

有个s函数,先跟进去看下是什么,他的2个参数,一个是哦,一个是t,如下所示
在这里插入图片描述
抖音直播wss链接 signature 分析(水一贴)_第11张图片

进去之后会发现进到这里面,到了这里就是熟悉的webpack了,我们要将这些调用先跑起来。

PS:关于 webpack 逆向,网上有很多优秀的教程。我这里就自己手动导出一下,因为数量不多,多的话,可以看看网上的自动输出方法,多学几种方法总是好的。

抖音直播wss链接 signature 分析(水一贴)_第12张图片

先在此处下一个断点,然后重新刷新一下,让他在这里断下

抖音直播wss链接 signature 分析(水一贴)_第13张图片
再单步进入到 n 函数里面

抖音直播wss链接 signature 分析(水一贴)_第14张图片

进去之后在return里面下断点,然后继续走到断点位置,然后,我们先把这当前的整个代码复制下来,放到本地运行,
然后在这里写一行,把他导出到全局
抖音直播wss链接 signature 分析(水一贴)_第15张图片

导出之后,我们就可以在全局上访问webpack里面打包的函数,到了这一步先别急,我们刚刚在前面看到的这几个就要添加进他到底大对象里面了,关于webpack的原理这里就不细说了,网上很多教程,毕竟我说了这是水贴

我这里是这样添加的,他第一个函数是 n(55535)
在断点的位置不要动,直接回到控制台输入u[‘55535’],他return后面跟的啥变量就用啥变量去获取,他是一个超大的对象

抖音直播wss链接 signature 分析(水一贴)_第16张图片
然后点进去,把这个对象的函数给复制下来

抖音直播wss链接 signature 分析(水一贴)_第17张图片

然后cv到你刚刚保存的那个文件里面的大对象里面,剩下的15353和4488以此类推

抖音直播wss链接 signature 分析(水一贴)_第18张图片

当你导进去之后,你就可以在控制台检测一下

抖音直播wss链接 signature 分析(水一贴)_第19张图片

到了这一步之后,回到前面,前面他是这么写的,r = n(55535), i = n(4488).utf8, o = n(15353),a = n(4488).bin,

这个n函数其实就是我们刚刚导出的 window.m

那么我们调用的时候就可以这样写了

抖音直播wss链接 signature 分析(水一贴)_第20张图片

然后呢,又因为我们刚刚的 var n = r.wordsToBytes(s(e, t)); 里面的 s 函数是来自这个84465的对象,并且他的入参就一个参数,我们要把这个84465的函数也给导出到webpack的对象里面,还是同理,cv到前面的那个地方。

抖音直播wss链接 signature 分析(水一贴)_第21张图片

cv之后,
抖音直播wss链接 signature 分析(水一贴)_第22张图片

可以打印看下结果,到了这一步就获取了X-MS-STUB的结果

抖音直播wss链接 signature 分析(水一贴)_第23张图片

继续回到原来的位置,可以看到,这里return都好表达式,最后数输出一个 Object 出来

抖音直播wss链接 signature 分析(水一贴)_第24张图片

继续回到开始的位置,在return的位置下断点,在控制台查输出看一下数据

抖音直播wss链接 signature 分析(水一贴)_第25张图片

会输出一个这样的东西,然后 signature: null != (o = a[“X-Bogus”]) ? o : “”,他又会去取X-Bogus 的value,作为他自己的值,进到 n.frontierSign,可以看到,是抖音的 jsvmp

抖音直播wss链接 signature 分析(水一贴)_第26张图片
进到函数里面,可以看到,他的入参,是刚刚我们通过**D()(i.substring(1))**计算出来的值

抖音直播wss链接 signature 分析(水一贴)_第27张图片
通过执行vmp,也是可以获取到数据
抖音直播wss链接 signature 分析(水一贴)_第28张图片

注意:到了这一步,先不要急,正常流程走的话,你应该要去验证一下这东西你分析了之后对不对,看生成出来的东西能不能用,而不是瞎鸡儿往下搞。(你也不知道他有没有给你埋其他的坑)

抖音直播wss链接 signature 分析(水一贴)_第29张图片

下面是一段nodejs的代码,方便后续验证signature的可用性

// webSocketUrl参数替换成你们自己浏览器的,除了signature不复制,其他都cv上去

const WebSocket = require('ws')

const signature = '' // 验证你的 signature
const userAgent = '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36'
const webSocketUrl = `wss://webcast5-ws-web-hl.douyin.com/webcast/im/push/v2/?app_name=douyin_web&version_code=180800&webcast_sdk_version=1.0.6&update_version_code=1.0.6&compress=gzip&device_platform=web&cookie_enabled=true&screen_width=1920&screen_height=1080&browser_language=zh-CN&browser_platform=Win32&browser_name=Mozilla&browser_version=5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/113.0.0.0%20Safari/537.36&browser_online=true&tz_name=Asia/Shanghai&cursor=t-1689264612798_r-1_d-1_u-1_h-1&internal_ext=internal_src:dim|wss_push_room_id:7255257051152730915|wss_push_did:7255323052254414347|dim_log_id:202307140010123EF135C24A944B5EF10A|fetch_time:1689264612798|seq:1|wss_info:0-1689264612798-0-0|wrds_kvs:WebcastRoomStatsMessage-1689264611462151237_WebcastRoomRankMessage-1689264389498438065&host=https://live.douyin.com&aid=6383&live_id=1&did_rule=3&endpoint=live_pc&support_wrds=1&user_unique_id=&im_path=/webcast/im/fetch/&room_id=7255257051152730915&identity=audience&heartbeatDuration=0&signature=${signature}`

const client = new WebSocket(webSocketUrl, {
  headers: {
    'User-Agent': `Mozilla/${userAgent}`,
    cookie: 'ttwid=1|dx-bBu3gXE-OyfoylJsWuKrqnpFRomgwBejsAmhRGhA|1689177319|d2996fa9a0beb84f6fb390a33c270011682d5ea10cbf407ed1c592fc350a0a92;'
  },
  binary: true
})

client.on('open', () => {
  console.log('###########     WebSocket open    ###########')
})

client.on('message', message => {
  console.log(message)
})

client.on('close', async () => {
  console.log('###########     WebSocket close     ###########')
})

client.on('error', err => {
  console.log('###########     WebSocket close     ###########')
})


到了这里,下面就是分析 如何让 vmp 在本地调用,主要还是补环境,大佬的话可以搞纯算


进到vmp之后,首先将这个东西给cv保存到本地,初始化的时候先运行这个,这里还要稍微修改一下
抖音直播wss链接 signature 分析(水一贴)_第30张图片
找到那个vmp调用的函数,然后给他放到全局去
抖音直播wss链接 signature 分析(水一贴)_第31张图片

然后直接就是在全局调用

抖音直播wss链接 signature 分析(水一贴)_第32张图片
抖音直播wss链接 signature 分析(水一贴)_第33张图片
然后我们去验证一下这个签名是否能用,发现是可以的
抖音直播wss链接 signature 分析(水一贴)_第34张图片

到了这里我们就算完成了80%,因为目前还是在浏览器运行的,剩下的就是nodejs补环境了。补的东西不多。修修补补,一下就能补好。他主要是对roomid进行了一个计算,每次只需要更换 roomid 然后计算出signature即可。

抖音直播wss链接 signature 分析(水一贴)_第35张图片

你可能感兴趣的:(前端,java,服务器)