AI智能
改变未来

【JS逆向】破解第三方B站视频下载加密策略

最近一段时间老板管的比较松,就跟着咸鱼大佬的公众号:Python 爬虫进阶必备 自学了一些JS逆向的知识,再加上自己的摸索得比较勤快,感觉还是有一些进步的,这篇文章算是一点点学以致用吧。

目标网站:

aHR0cHM6Ly94YmVpYmVpeC5jb20vYXBpL2JpbGliaWxpLw==

(看到最后的==,你应该知道这是什么编码了吧)

前段时间对B站视频的下载方法比较感兴趣,一路顺着谷歌→GitHub→微信公众号找到了这篇文章:宝藏B站UP主,视频弹幕尽收囊中!

文章写的特别详细,可惜的就是那个下载的接口失效了,于是我就想自己动手试一试。

抓包和定位

找到提交的表单信息:表单信息很明显,第一个参数是待解析的B站链接,第二个为是否增强解析的参数,设置为True。预览一下响应内容,可以看到MP4地址这一栏是空着的,那说明这部分内容是动态加载进来的。预览响应打开开发者模式,映入眼帘的就是一个草泥马,说明这个网站不想让人爬它,但是可惜我还年轻,不讲武德。

破解无限debugger

其实打开开发者模式,第一眼看到的不是草泥马,是一个

debugger

,滑到最上面才看得到草泥马。这个

debugger

会让我们卡在这里,陷入死循环。但是这个其实很好破,右键添加条件断点

Add Conditional breakpoint

,然后条件设为

false

,这个时候无限

debbuger

的反爬就被我们绕过了。debugger刷新页面,将待解析的b站链接输入文本框并点击“解析视频”,又出现一个

debugger

,用同样的方法解决。

定位加密点

hahaha

这里添加一个断点,刷新页面这时发现MP4地址这里空了,说明这一步是关键的一步。

F11

进行下一步,发现加密的地方然后在控制台测试一下,发现这就是我们想要找的MP4下载地址于是现在我们需要分析一下这个

decrypt

函数。

破解加密策略

点击

decrypt

函数进入他的内部,可以看到所有JS代码都是加了混淆的,代码的可读性变的特别差,例如这样:

function decrypt(_0x55cd15) {
    var _0x2b29a5 = CryptoJS[_0x4525(\'0xd\', \'p(J)\')][_0x4525(\'0xe\', \'ZJjv\')][_0x4525(\'0xf\', \'2W(k\')](_0x4525(\'0x10\', \'R!FI\'));
    var _0x431fea = CryptoJS[\'enc\'][\'Latin1\'][\'parse\'](_0x4525(\'0x11\', \'N6Ge\'));
    var _0x28806e = CryptoJS[_0x4525(\'0x12\', \'U[)g\')][_0x4525(\'0x13\', \'u4yX\')](_0x55cd15, _0x2b29a5, {
        \'iv\': _0x431fea,
        \'mode\': CryptoJS[\'mode\'][_0x4525(\'0x14\', \'R!FI\')],
        \'adding\': CryptoJS[_0x4525(\'0x15\', \'KvSw\')][_0x4525(\'0x16\', \'eITC\')]
    })[_0x4525(\'0x17\', \'o*r^\')](CryptoJS[_0x4525(\'0x18\', \'ZH@&\')][_0x4525(\'0x19\', \'o(Cg\')]);
    return _0x28806e;
}

于是放弃复现,而是把所有用到的JS代码全部扣出来,然后用Python的

execjs

库来运行这些JS代码。注意这里它用了

CryptoJS

库,这个库可以用

npm install crypto-js

安装到本地后,再用

require

来导入即可。

const CryptoJS = require(\"crypto.js\");

代码实现

首先定义调用JS代码的Python函数:

def get_js_function(js_path, func_name, *args):
    \'\'\'
    获取指定目录下的js代码, 并且指定js代码中函数的名字以及函数的参数。
    :param js_path: js代码的位置
    :param func_name: js代码中函数的名字
    :args: js代码中函数的参数
    :return: 返回调用js函数的结果
    \'\'\'

    with open(js_path, encoding=\'utf-8\') as fp:
        js = fp.read()
        ctx = execjs.compile(js)
        return ctx.call(func_name, *args)

然后用正则表达式获取密文

hahaha

,并完成解密,这里的

r.text

是获取到的响应的文本形式。

hahaha = re.search(\"hahaha = \'(.*?)\';\", r.text).group(1)
download_url = get_js_function(\'bilibili.js\', \'decrypt\', hahaha)

需要注意的是,获取得到的下载链接只是一个临时链接,2个小时后就会失效,所以是不能长期用来在线观看的。url中包含deadline这么一个参数

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 【JS逆向】破解第三方B站视频下载加密策略