• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

dy9527

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

抖音a_bogus,mstoken全参数爬虫逆向补环境2024-06-15

除了抖音还包括快手,小红书,哔哩哔哩,微博,京东,淘宝等平台,旨在帮助大家学习使用
接口及参数
打开网页版抖音,右键视频进入详情页。
F12打开控制台筛选detail,然后刷新网页,找到请求。
可以发现我们本次的参数目标a_bogus。a_bogus有时长度为168有时为172,都可用。
msToken在cookie中可以获得msToken,过期时间为7天。
screen_width、screen_height对应cookie中的dy_swidth、dy_sheight。
cpu_core_num、device_memory对应cookie中的device_web_cpu_core、device_web_memory_size。
verifyFp、fp对应cookie中的s_v_web_id。
webid可以从doc中获得user_unique_id。
QQ_1756106496562
QQ_1756106541418
QQ_1756106575057
找到加密代码
找到入口

首先看一下接口的加载器,也就是发送请求的调用栈,挨个查看之后不难发现,加密的入口应该在这两处,由于栈中的调用顺序是从下往上,所以我们先看下面那个入口。
QQ_1756106692739

查看参数

首先我们查看入口参数,不难发现arguments[1]是请求的url,那么我们可以根据url包含detail去打一个断点,然后一步一步进行调试,看看发生了什么。
QQ_1756106735205

断点调试

单步步入之后,开始了加密参数的流程,我们发现这里的代码明显是混淆过的,上下翻动后,我们发现这是jsvmp文件。单步跳出后,直接到了请求流程,说明在这里面已经完成了a_bogus的加密,所以我们可以断定,加密参数是在调用栈中另一个地方调用的。所以我们再查看一下调用栈中的另一个入口。
QQ_1756106788031
可以看到,加密最后运行的函数是s.apply(b,u)并且赋值给了l,那么我们可以大胆猜测一下,这个l就是返回的加密结果,但是我们知道request中有很多加密参数,而且这个代码是jsvmp,所以我们可以认为,这里是调用了jsvmp的指令函数,这个指令函数加密了我们的a_bogus,但是也被其他的一些需求调用,所以说我们要定位到加密a_bogus的时机。
QQ_1756106830955

我们可以知道a_bogus的长度为172,所以我们可以在这里打条件断点,当s.apply(b,u).length === 172时断住。然后进行观察。
QQ_1756106862281

断住之后,我们发现结果大概率是我们要的a_bogus,后面我们会验证一下,参数为uri以及UserAgent。那么我们之后调用的时候,可以直接调用这个函数,把相应的参数传进去就可以得到我们想要的结果。由于这个s.apply可能调用的函数有很多种,我们不知道它调用的具体函数是哪个,因此,我们需要找到函数调用入口也就是函数导出。至此我们先验证一下结果。

QQ_1756106893710

QQ_1756106908959

补环境
首先我们把整个bdms.js拿下来,本地运行,进行补环境。

然后运行后发现window is not defined,我们定义一个window=global补个window环境再试试看。

QQ_1756107018115
我们发现这里莫名其妙报了个错,由于代码混淆加上各种循环,很难找到这个变量是什么,所以我们猜测,大概率是获取某些环境没有获取到,所以我们加代理看看他获取了什么没获取到导致的。我们添加下列代理来看看检测了哪些环境。
QQ_1756107160723
我们发现,检测的还不少。加上代理之后我们发现,在访问wondow.requestAnimationFrame时没访问到,然后紧接着报错了,那么说明,对window.requestAnimationFrame进行了校验,因此我们可以补一下 ,这个是一个函数,我们补一个空函数试试。

QQ_1756107237394
补完后发现又有报错。我们发现访问window._sdkGlueVersionMap时XMLHttpRequest报错,那我们都补一下。我们可以到浏览器的控制台获取window._sdkGlueVersionMap的值。
QQ_1756107266875
QQ_1756107283864
全部补完之后我们发现终于没报错了,说明正常运行了,下一步我们需要找到加密函数的入口,然后进行最后的加密操作。
QQ_1756107318436
函数入口
我们重新断点进入,看看到底调用了什么,我们可以发现,首次调用的函数是这里,我们可以单步调试进去看一下什么时候调用的s.apply。
QQ_1756107343315
断住之后,我们进去看看什么时候调用到了我们需要的s.apply,所以我们需要在s.aaply处打个断点。打住断点之后,由于我们之前在这里断点过,所以我们可以通过查看u[3]的url是否包含我们的本次请求detail查看。
QQ_1756107394249

断住s.apply后,我们可以知道这里调用的函数就是我们需要的导出的函数,我们单步步入,发现是这个函数。这个函数的样子我们好像见过,没错这个函数有好几处,我们可以通过59 !== m找到他。我们可以看到实际上u = function (),把加密函数赋值给了u,所以我们直接在这里导出即可,对了,别忘了加上
QQ_1756107430707
QQ_1756107463534
其中我们发现,调用sign之后又多检测了很多环境变量,为了环境更加真实和防止被检测的风险,尽量补全环境是最好的,即使会降低运行速度,如果追求运行速度我们可以尝试难度更高的纯算逆向。

而且补空函数并不能通过环境的检测,因此我们需要把整个环境补全,最终补全的环境代码如下:
QQ_1756107505775

全环境补完正确结果
需要注意的是,环境检测远不止这一点,还有dom之类的检测,这部分大家可以通过断点一步步调试,最终补好所有环境。
QQ_1756107537165

QQ_1756107554639

QQ_1756107569414

成功!!!

需要注意的是,每个接口加密参数不同需要自己去探索,其中详情接口和回复接口如下:
QQ_1756107597144

posted on 2025-08-25 15:41  chriski  阅读(891)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3