本帖最后由 ReverseJourney 于 2024-12-20 21:50 编辑
本文章中所有内容仅供学习交流,不用于其他目的,抓包内容、敏感网址、数据接口等均已做脱敏处理。若有侵权,请联系作者删除。
一、前言
该APP难度中等,非常适合想要学习Android逆向进阶技巧的小伙伴练手,对如何快速定位关键函数以及如何调用openssl库还原算法都很有帮助。
二、准备
FrIDA
IDA
UltraEdit
Fiddler
三、分析
随便打开一本书阅读,可以看到Fiddler抓到了几个请求,粗略看一下发送内容和返回结果,说不定等下分析的时候寻找参数来源可以用到,如图所示:
1.定位so
hook fopen并打印堆栈,得知在libddlayoutkit.so里对文件进行了操作,也定位到了epub存放路径和关键解密函数,如图所示:
2.流程分析
将/storage/emulated/0/Android/data/com.dangdang.reader/files/ddReader/undefine/readbook/1901308171/1901308171.epub pull出来,解压查看文件结构,container.xml记录了文件的加密信息,如图所示:
IDA打开libddlayoutkit.so,定位到DangDrm::decrypt看下伪代码
hook DrmImplN::encryptAdDecryptDes和DrmImplN::encryptAdDecryptAes,确认下这本书籍是走哪个分支。发现2个函数都调用了,这就很奇怪了,看伪代码要么执行DrmImplN::encryptAdDecryptDes要么执行DrmImplN::encryptAdDecryptAes,不会2个分支同时执行,得打印下堆栈进一步判断,发现DangDrm::deCryptSecretKey调用了DrmImplN::encryptAdDecryptDes,如图所示:
通过输出结果可以判断执行的是最后一个分支。
(1)分析DangDrm::deCryptSecretKey
跳转到DangDrm::deCryptSecretKey,发现可疑函数
IDA切换到Disassembly视图
需要写Frida脚本计算类的成员函数地址,脚本如下:
[JavaScript] 纯文本查看 复制代码 calcFuncAddr();
function calcFuncAddr()
{
var baseAddr = Module.findBaseAddress("libddlayoutkit.so");
console.log("baseAddr:"+baseAddr);
var addr=baseAddr.add(0x14C220);
Interceptor.attach(addr,
{
onEnter: function(args)
{
var x8=this.context.x8;
var funcAddr=x8-baseAddr;
console.log('target funcAddr:'+ptr(funcAddr));
},
onLeave:function(retval)
{
}
});
}
执行脚本后输出如图所示:
IDA跳转到0x14821C,发现是Base64解码函数
IDA伪代码,如图所示:
hook Base64::decode_cert,输出如图所示:
lyMTr7mu!oJxwwPj7aAPixNxhv!GCxkpaMX6ByT65JpChDddhn8m9VeoMlXeofLigPLkwhrxNwKxS-LhtzK3ea==似曾相识,经过查找,在getPublishedCertificate请求返回的结果里找到该字符串
对该字符串解码,发现怎么解都解不开,匪夷所思,猜测是魔改Base64,得继续分析Base64::decode_cert,跳转到该函数查看内部逻辑,发现Base64码表被修改了
代码复现:
继续分析DangDrm::deCryptSecretKey内部逻辑,发现可疑函数DrmImplN::decryptDataByEvpPriKey
DrmImplN::decryptDataByEvpPriKey伪代码
hook BIO_new_mem_buf
hook EVP_PKEY_decrypt_old
调用openssl库复现
得到了16个字节bf ba b0 e5 58 bf fc 3a 16 b1 78 73 18 d8 67 e1,猜测可能是AES密钥。
(2)分析DrmImplN::encryptAdDecryptAes
DrmImplN::encryptAdDecryptAes逻辑很简单
hook AES_set_encrypt_key和AES_cbc_encrypt,输出如图所示:
AES解密后得到明文,至此解密流程已经很清晰了。
3.解密算法
首次打开书籍时,会发送getPublishedCertificate请求到服务器,读取返回结果中的key字段,如图所示:
将该字符串Base64解码(魔改Base64),将解码后的Base64进行RSA解密得到AESKEY,AESIV为16个0,读取OEBPS目录下的加密文件进行AES CBC解密,就可以还原成正常epub,如图所示:
|