记录一次对ximalaya的简单JS逆向

2月中的一天,我发现自己的喜马拉雅音频解析脚本频繁报错。我赶忙到浏览器控制台一看,音频接口的playPath字段,已经成了空字符串。喜马拉雅免费音频的接口地址更迭频繁,23年年底做过大改,但好在虽然改版,但依然返回明文URL,不需要做解密。新的音频接口并不难找,但这次接口的参数更多,回传值也以密文取代了明文。想要拿到真实的URL,那么JS逆向必不可少了。

一、接口具体变化

1、接口不再显示明文音频地址,取而代之的是一段无法分辨加密方法的密文,例如

DSgBNxQ8BT6htKLZNN-DrkrOjntz48MXMgOM4unN4r3hDoeyFP09YRmZ9Go7vBNfxSEtpI44OcpnZAeg9inSS0gwO8dGwY8kTQDbb6i15MdlwEYrre3IOSe6gC99hbFTEwHbx00FPaotr124NbuKOQDlnQhcw8BG

2、原先的免费音频接口不需要cookie鉴权,如今的音频接口必须要通过登录获取cookie字段1&_token来鉴权,才会显示密文URL。

二、操作

仔细分析新版的接口URL:

https://www.ximalaya.com/mobile-playpage/track/v3/baseInfo/1707881982940?device=www2&trackId={}&trackQualityLevel=1

不难看出1707881982940是一个十三位时间戳,trackId也就是专辑ID,和原来比变化不大。那网上有没有现成的教程呢?我一番搜索下,找到不少非常类似的,针对喜马拉雅web接口的解密教程。但我这个是www2接口呀,不知道能不能用上,先沿着前人方法一试吧。我开了全局搜索decrypt和AES,很快定位到了前辈们用来解密的代码,于是在此处打了个断点。按下F5,这段代码并没有被触发。

尝试失败,前人的经验宣告无效。这时我看见这个弃用代码下方,有一个playUrlList,这个字段和音频接口返回的键值一模一样,于是我在这里打了个断点:

我不断step next,一边观察右侧面板参数的变化,突然,断点停在一个三目运算符上。代码显示 src: r._options.decryptFn ? r._options.decryptFn(u) : Lt(u),其中Lt就是用于web接口解密的函数,运行显示二选一进入了decryptFn这个函数,没有进入Lt。其中decryptFn接收的参数u,就是playUrlList[0]的密文url,这里可以看清楚一些:

这次我选择step into进入,看一下这个decryptFn到底长啥样。结果他停在了一个叫getSoundCryptLink的函数上,此时我已经感到如释重负,逐步逼近真相了。

全局搜索getSoundCryptLink,这次我在函数内部最上方位置和return位置分别打上断点,看传入参数和返回值究竟是什么。

第一个断点处,可以看到传入的e参数为一个字典,有两个键,分别是deviceType和link:

第二个断点处,返回值已经变成了明文URL:

要的解密函数找到了!我仔细观察getSoundCryptLink,该函数一开始从传入参数e中提取t(密文URL)和i(设备类型)后,便进行了[“www2”, “mweb2”].includes(i)的判断。我尝试了一下将i的值改为web或者www,函数可以正常运行,但无法返回正确的URL,i的值必须为www2或是mweb2,才能正常解密。

后续我参考了吾爱破解一些大佬的经验,不打算将其转换成Python代码了,直接保存为JS文件后用PyExecJS调用。

我继续看了一圈关于喜马拉雅音频下载的油猴脚本,发现不说100%,可能95%以上的脚本,依然通过web接口这个方法来获取音频地址。但就目前趋势看,现在所有的网页请求全部都是www2接口,web接口早已不再显示,未来这个接口下线并不是不可能。

注:这是我2月14号左右想做的小逆向,但不幸受伤了休息了一段时间,现在才有时间将这段经历总结成文章。这也是本人第一个逆向小尝试,有错误遗漏欢迎大家指教。

发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注