声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关.本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责。
需求
下载目标网站的书籍。
目标网址
aHR0cHM6Ly9oNS5tZXRhcmVhZGVyLmNuL2g1L3BhZ2VzL3BjL3dlYj9iaWQ9MTA2NDg4OTg5NjQwMzAyMDgmYXBwSWQ9MGJpZGc1MnImdGVuYW50SWQ9MTAxMDAxJmluZGV4PTA=
前言
前一段时间发布过几篇关于期刊、书籍网站解析下载pdf、epub的文章(博看网期刊下载生成pdf【实操AI编程】,QQ阅读·机构版解析生成EPUB电子书,期刊网杂志解析生成PDF(完整解析流程+源码)),因为基本没有什么加密,没什么逆向的必要,就直接分享代码了,本次的网站就稍微多了一点加密,姑且发布在这里做一个记录,web逆向方面我还是个小白,感谢各位大佬支持和指导~
逆向过程
抓包分析
- 先过一边接口,凭借经验把有用的记录一下,做到心中有数。
- 查看下载资源。
这里其实挺明显的,来回翻页的时候发现书籍每一页都会加载一个独立的epub文件进行解析显示。直接下载发现可以下载但是无法打开。
正常的epub文件时直接可以用解压文件打开的,这里说明被加密了。那我们就需要解密epub文件。
解密EPUB文件
查看分析处理epub文件部分的代码。
看上去很是很是顺利,甚至已经注释了解密书籍的函数,看一下发现用的CryptoJS
验证解密方式
下个断点看一下url和password
测试一下:
const CryptoJS = require('./crypto-js.js');
const fs = require('fs');
async function getEpubContent(url) {
const https = require('https');
return new Promise((resolve, reject) => {
https.get(url, res => {
const chunks = [];
res.on('data', chunk => chunks.push(chunk));
res.on('end', () => resolve(Buffer.concat(chunks)));
}).on('error', reject);
});
}
function decryptedBook(buffer, c_key) {
const key = CryptoJS.enc.Base64.parse(c_key);
const encrypted = CryptoJS.lib.WordArray.create(buffer);
return CryptoJS.AES.decrypt(
{ ciphertext: encrypted },
key,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
).toString(CryptoJS.enc.Latin1);
}
(async () => {
const password = "";
const url = "";
try {
const buffer = await getEpubContent(url);
const decrypted = decryptedBook(buffer, password);
fs.writeFileSync('decrypted.epub', decrypted, 'binary');
console.log('解密成功!');
} catch (error) {
console.error('处理失败:', error);
}
})();
查看解密后文件:
发现已经可以正常打开,且文件内容正常,至此,已完成一半内容,接下来需要找到url和password。
获取password
其实url在浏览接口的时候就已经看到了:
那么只需要找到password的生成方式。
抓包分析
最开始过接口的时候就已经有猜测了:
api/front/drm/auth/book
这接口名又是drm又是auth的,其实很大程度上可以确定这个接口跟加密相关了,更何况data里还有encrypt
这么直白的参数
代码分析
先检索api/front/drm/auth/book
找到authBook
,再次检索
只有8个结果,且在同一文件下,全部打上断点。
这里发现了刚才的password的值,
进入到关键函数T,再次打上断点。
可以看到就是此处生成的,而且代码上看使用的JSEncrypt。
验证解密方式
对于PrivateKey其实接口里面就看到过,走一下形式,检索一下:
验证
用其他书籍验证成功,此处略过。
其他参数
所需的参数实际上只差header中的token以及deviceid,因为需求是“下载目标网站的书籍”,所以不做分析,直接在header和localstorage中获取即可。
后续处理
接口完整且加密部分使用的标准库,并没有魔改,可以直接改写成其他语言,只需要遍历目录,全部下载后可合并成书籍的完整epub文件。(本文只提供加密部分的逆向分析,不提供完整代码)