网站首页 > 技术文章 正文
缘起:果酱视频原名为茄子视频,是早期的一种水果软件,偶然在52pojie网站上看到该app的逆向破解,但是并没有提供具体细节,应该是作者怕出问题。从作者的提示中发现该网站的VIP视频是可以破解的,于是着手进行逆向。但是app进行了加固,由于本人并没有脱壳经验,所以选择了他们的web网站进行js逆向。
本文主要涉及:JS逆向,flutter框架的web逆向,AES加解密,m3u8下载
主要加密点:请求头中D参数加密,请求体加密,返回图片加密,m3u8加密
收益:主要总结逆向的流程及思路,以及一些逆向小技巧。技巧点会以<技巧>(1)标识
分析网络请求
首先打开F12进行网络抓包,随便找一个url点开查看,发现两处加密点,第一处位于请求头的D参数,第二处位于请求的响应数据,如下图
二、debug分析
加密本身并看不出有什么特别之处,那就直接下断点,点开=发起程序=选项卡,点第一个发起的程序下断点
b.send,猜测b为xhr对象,send为发送请求。那此时可以使用HOOK来断住xhr,当然也可以跟着调用栈进行分析,这里两种方法效果是一样的。我们进行一下hook断点<技巧>(1)
1.加密方法
(function () { var open = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function (method, url, async) { debugger; return open.apply(this, arguments); }; })(); |
将上述代码输入到控制台中,然后继续请求,发现断住的位置来到了xhr新建的地方,但是这里请求参数和请求头的加密参数早已经生成完毕。只能跟栈分析。
对于逐步代码分析来说没有什么太好的方法,但是却是最有效的方式。在debug过程中不能只是盯着需要找到的点进行debug,这样的话很快就会被框架的来回调用导致没有耐心。比如这个flutter框架,类似webpack模式,他会进行许多懒加载以及代理调用,所以在debug时会发现无论什么方法好像都会进入同一个方法然后找不到真正的源头(因为源头总是flutter的源码)。所以这里也就引出,不能依赖跟栈,要时不时终止断点来正向单步调试<技巧点>(2)。
回到这个网站本身,在寻找这个请求头中的D参数到底是从那里来时,我们在栈中发现。在调用aEy方法时参数al已经有值,那么就有看调用aEy的是谁,但是我们发现,无法继续向下跟栈,无论无何跟栈都是回到了flutter的调用中,无法找到谁真正的调用了aEy(我猜测是flutter发送xhr是只需要告诉flutter要发送什么,而不需要自己调用xhr。Flutter会自己处理后会异步发送请求)。
至此已经无法靠跟栈来获得解密方式了,尝试直接搜索url可以找到和发送有关系的代码,在这里打断点然后一步一步向下调试,
通过一步一步进行调用查看功能发现
- bnX()为加密方法,内部又调用了a3N
直接给出加密代码
这里是AES加密方式,总的来说是先将请求的json进行一次md5加密后得到s,再把s放入json中进行一次AES加密,就可以得到密文。至此其实已经可以构造本网站的所有请求。
m3u8获取
此时我们可以构造本网站的所有请求。那么我们随便点开一个视频进行播放,发现他会进行一次playNew的请求获取到m3u8的地址,随后我们打开这个m3u8文件以及请求头查看一下。
我们可以发现,他没有带任何鉴权。而且m3u8文件虽然不是完整视频文件,但是我们是否可以构造后续ts文件链接来补全视频文件。经过实验确实可以,具体流程就是获取到视频完整时长,然后构造后续ts链接,将新的m3u8文件进行播放或者下载发现可行!
总结
逆向是需要一点运气和很多耐心的工程。本次逆向其实可以算的上失败,虽然最后成功找到了加密点也做出了破解,但是基本上是靠单步调试来实现的。Flutter框架本身的xhr请求完全无法定位到本身的加密点,只能透过一点点线索来找到真正的代码逻辑。
本次逆向重点转折点是直接搜索请求链接,然后顺着请求连接正向debug找到了加密点,在这个过程中需要时刻注意加密是否完成,如果加密完成则倒回去一步一步寻找是哪个函数进行加密。
同时也要善用工具库来进行密文比对,这样可以不用看具体实现,在console中直接运行代码后进行比对,如果比对成功则直接使用即可。
- 上一篇: 揭秘:视频播放网站如何精准记录用户观看进度
- 下一篇: 前端面试题《AJAX》(前端面试题js)
猜你喜欢
- 2025-07-09 跨域资源的共享(CORS)N种用法(跨域资源共享的缩写是?)
- 2025-07-09 Axios CORS 问题处理(axios has been blocked by cors policy)
- 2025-07-09 JavaScript-JavaScript 219
- 2025-07-09 前端面试题《AJAX》(前端面试题js)
- 2025-07-09 揭秘:视频播放网站如何精准记录用户观看进度
- 2025-07-09 国外友人开创Python模拟登陆神库,完美修改它为咱们所用
- 2025-07-09 Ajax异步JavaScript和XML(ajax异步原理)
- 2025-07-09 2021年超详细的java学习路线总结—纯干货分享
- 2025-07-09 webapi 全流程(webapi怎么部署)
- 2025-07-09 Python精彩解析反反爬虫,采集各行业招聘数据,分析行业行情
- 1509℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 533℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 496℃MySQL service启动脚本浅析(r12笔记第59天)
- 475℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 473℃启用MySQL查询缓存(mysql8.0查询缓存)
- 453℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 432℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 430℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)