一、准备
钉钉版本:7.6.25-Release 110510808
x64dbg
IDA
010 Editor
二、分析
在分析数据库加密之前,先大致判断数据库采用了哪种加密算法。通常加密数据库有以下几种类型:
1.魔改标准sqlcipher加密算法[AESECB XXTEA等](钉钉 QQ)
2.wxsqlite(企业微信)
3.标准sqlcipher(微信、QQNT、蝙蝠、signal等)
其中标准sqlcipher出现得最多。
聊天数据库路径:
C:\Users\xxx\AppData\Roaming\DingTalk\xxxxxxx_v2\DBFiles
打开一个较小的钉钉数据库,比如calendar_v2.db,可以看到16字节对齐的重复数据,这种特征不是AES ECB就是XOR解密,这一片区域原始数据都为0。

1.png (95.56 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
确定目标模块
钉钉有3个进程,附加有标题的那个进程。

2.png (20.52 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
x64dbg下断点 bp CreateFileW,登录钉钉,断下后查看堆栈,调用来自mainframe.dll。
1.定位sqlite3_open/sqlite3_open_v2/openDatabase
从源码得知sqlite3_open和sqlite3_open_v2都会调用openDatabase,
openDatabase里面有些常量字符串可以用于定位。如图所示:

3.png (26.95 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
openDatabase函数内部的字符串

4.png (31.48 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传

5.png (26.91 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
可以通过搜索"BINARY" 、"NOCASE" 、"RTRIM" 、"main"、"temp"等字符串定位openDatabase。
在mainframe.dll中搜索"NOCASE",下断点然后登录钉钉,登录成功会在打开数据库时断下,如图所示:

6.png (89.73 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
断下来的地方位于openDatabase内部,跳出此函数,就定位到了打开数据库函数,如图所示:

7.png (101.86 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
2.定位sqlite3_key
定位sqlite3_key有2种常用方案
(1)定位到打开数据库函数之后,一般情况下在往下不远处会出现设置密钥call,找不到就跳出这层call往上层跟踪可疑函数。
(2)通过"main"字符串定位,openDatabase内部也出现了"main"字符串,也会断下来。但有时候一些程序直接调用sqlite3_key_v2打开数据库,并不会出现"main",从而定位不到设置密钥函数。源码如图所示:

16.png (34.12 KB, 下载次数: 0)
下载附件
2024-12-19 13:45 上传
往下运行,找到了非常可疑的设置密钥call,x64dbg 按F7进入sub_181E00E30。
sub_181E00E30如图所示:

9.png (130.25 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
查看sub_181ED0660

10.png (351.76 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
可以看出IDA伪代码和源码sqlite3CodecAttach十分类似,
sqlite3Codec(sub_181E30BF0)是最关键的函数之一,里面存在具体的加密算法和
[color=]页大小
,如图所示:

11.png (418.26 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
对181FA2A90下断点可以看到解密后的明文数据

12.png (57.55 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
现在流程已经很清楚了,数据库密钥为
e0b8449af5de06ecb36b182970bfbadf22197016915918185882701231384169
加密算法是AES_ECB算法,但现在又有一个问题,如何确定密钥长度到底是16、24、32呢?
3.如何确定密钥长度
(1)可以写代码依次截取前16、24、32位作为AESKEY解密数据库。
(2)分析setaeskey(sub_181E298F0)

13.png (30.7 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
在sub_181FA1E30处下断点,rcx=密钥,rdx=AES类指针,F8步过,看到AES类指针如图所示:

14.png (81.21 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传
该函数进行了 字节代换、行移位、列混合、轮密钥加,共计10轮,所以密钥长度为16。
4.解密流程
MD5(uid).substring(0,0x10)得到AESKEY,AES_ECB_NoPadding解密数据库得到明文。写代码还原数据库,如图所示:

15.png (208.78 KB, 下载次数: 0)
下载附件
2024-12-19 13:30 上传