转载自公众号:取证者联盟
目录
1. 前言
2. 准备工作
3. 内存镜像解析
4. 踩过的坑和感悟
5. 技术要点总结
前言
某年月日,我司在项目中遇到了一个不太常见的需求:根据内存镜像解析电脑中的某即时通讯软件(即“某信”)的聊天信息。在与供应商进行沟通以后我们了解到,市面上国内外几款比较流行的取证软件虽然支持针对某信Windows端的解析,但是大多还是需要用户扫描二维码进行登录。对内存的解析只有一家产品支持,实际试用后也遗憾地失败了。事后分析可能是与操作系统及某信软件的版本有关。
然后我们又在网上进行了一系列的搜索。虽然确实查到许多资料描述如何解析某信数据库,但是其中对内存镜像进行解析的内容几乎为零。我们只能摸着前人的石头过河。所幸走了不少弯路以后还算有了一个比较满意的结果,这才有了这篇小文。
****对于Volatility内存分析工具有一定认识的朋友可以直接查看结尾的技术总结。***
准备工作
登录某信后,使用FTK Imager制作笔记本电脑的内存镜像。
- 登录某信
- 使用FTK Imager制作内存镜像
在这里有几个选项,是否需要保存pagefile(“Include pagefile”)以及是否需要制作AD1格式的镜像(“Create AD1 file”)。经过测试在解析密钥时并不需要这两个功能,所以为了节约时间我们这里就不用勾选了,毕竟pagefile的文件大小还是很惊人的。
这一步大概花费5到10分钟,根据内存的大小不同。
3. 拿到内存镜像后不要就觉得万事大吉了。密钥密钥光有钥匙没有门我们不是一顿白忙活?
请记得制作笔记本电脑镜像并从中导出某信数据库文件。具体步骤这里就略过了。某信数据库的默认地址为“C:\Users[Windows User Name]\Documents\WeChat Files[WeChat account]”。
内存镜像解析-Volatility
铺垫了这么久终于可以上主菜了。这里解析内存镜像我们还是用Volatility。
Volatility是一款开源内存取证框架,能够对导出的内存镜像进行分析,通过获取内核数据结构,使用插件获取内存的详细情况以及系统的运行状态。
软件官网:https://www.volatilityfoundation.org
Github主页:https://github.com/volatilityfoundation/volatility
- 分析内存镜像并判断适用的配置文件(profile)
命令:volatility.exe –f memdump.mem imageinfo
Volatility需要从用户配置文件中读取内核的相关信息,通过这些信息来定位内存中的关键信息并对其进行解析。因此我们需要获取用户配置文件,且这些配置文件需与你要分析的内核版本相匹配,其中包含了内核数据结构以及调试符号。
这里个人将用户配置文件理解成一张地图,而内存镜像就是对应的实际地形。由于不同的系统版本对应不同的地图,只有使用相匹配的地图Volatility才能带我们找到想要的东西。
这一步会花费几个小时起步的漫长时间。所以个人建议先对笔记本硬盘镜像进行分析,然后根据操作系统的信息判断适用的配置文件会比较快。
2. 寻找某信进程的pid
命令:volatility.exe –f memdump.mem --profile=****Win7SP1x64** pslist >pslist.txt
*粗体下划的****Win7SP1x64****为配置文件名称,使用时请根据上一步结果/具体情况进行修改。
这里我们使用命令pslist将内存镜像中所有进程列表导出到文档文件pslist.txt中,然后查找WeChat.exe即可得到该进程pid为1072。需要注意的是在实际分析过程中这一步可能得到两个或者更多的pid。我们可以通过后面的分析或者根据是否存在Exit时间排除已经退出的进程。
- 寻找WeChatWin.dll的基址
命令:volatility.exe –f memdump.mem --profile= Win7SP1x64 ldrmodules –p 1072 >dlllist.txt
使用插件ldrmodules将pid为1072的进程所有关联的dll文件导出并查找WeChatWin.dll的基址。此处为0x53210000。
这里我们也可以使用Volatility自带的命令dlllist来查询关联的dll文件。但是插件ldrmodules可以关联部分隐藏的dll,功能更为强大。实际项目过程中我们发现部分电脑ldrmodules可以找到,而部分电脑ldrmodules无法找到而dlllist可以找到。所以个人建议两个命令都试下。
- 查询某信数据库密钥
命令:
volatility.exe –f memdump.mem --profile= Win7SP1x64 volshelll
cc(name=”WeChat.exe”)
dd(****base address of** WeChatWin.dll + **fixed offset****, length=4)
#返回结果为数据库密钥地址
db(****address of decryption key****, length=32)
#返回结果为数据库密钥
Volshell插件用来进入Volatility的shell,在该shell中可以使用cc命令来切换当前进程,使用dd和db命令分别打印dwords和具体bytes内容到屏幕上。
这里我们使用volshell插件进入shell以后使用cc命令切换到WeChat.exe进程。由于数据库密钥地址为32位的dwords,所以这里我们使用dd命令将该地址打印到屏幕上。需要注意的是这里我们使用“0x17734a8”来获取密钥地址,该常数根据某信版本不同可能有所变化。在这里测试所使用的版本为某信2.9.5.41。该常数的获取需要一定的逆向工程知识,网上也有很多现成的资料,在这里就不赘述了。
(参考:《PC某信逆向:两种姿势教你解密数据库文件》,链接地址:https://blog.csdn.net/qq_38474570/article/details/96606530)
最后在获得密钥地址为“0x07bc0a70”后,我们使用db命令将32位的密钥打印到屏幕上。
5. 使用获得的密钥即可解密数据库并查看具体内容。
某信Windows端使用sqlcipher进行加密,配置环境后可以使用SQLite进行解密。
那么关于某信数据库的解析到这里也就圆满结束了,剩下的工作就是将数据导出成Excel等易于查看的格式。
踩过的坑和感悟
首先是第一个大坑,不知道是不是我搜索的姿势有误,但是感觉内存取证方面的资料明显没有计算机取证/移动端取证那样丰富,仅有的资料也有些晦涩难懂。不知是否因为内存取证门槛相对较高?市场上能找到的也就Volatility一家,官网最近的更新时间还是2016年。虽然Github上能看到他们家在推新版本(Volatility3,Github主页:https://github.com/volatilityfoundation/volatility3),但是插件的开发好像还没有跟上。我们一度由于陈旧的版本缺少支持最新Windows系统的profile而无法进行。然后在实际项目中也遇到了由于不同系统版本和某信版本导致的众多小问题。例如在查询某信进程pid时碰到多个进程,需要仔细分辨那些是之前已经结束的进程而那个才是当前运行的。在查询WeChatWin.dll时也有ldrmodules插件无法查询到而Volatility自带的命令dlllist反而可以找到的情况。在最后查询数据库密钥时也碰到因为某信版本不同而需要回头对硬盘镜像中的某信程序进行逆向分析来判断所使用的常数。只有掌握全面的技能才能兵来将挡水来土掩。
絮絮叨叨说了这么多,其实最后真正有用的可能也就7行命令和1个常数。但是为了得到这些,我们却花了将近一周的时间。好在最后结果还是相对圆满的,达到的客户的期望。之前对内存取证的认识一直停留在做题的阶段。打比赛也好能力验证也罢,对这方面的内容似乎都只是浅尝辄止。在平时工作中就更少碰到这方面的需求了。通过这次小小的研究也让我对内存取证和某信解析有了更加深入的认识。之前也一直听说某信Windows端的数据库密钥只有在登陆时才能从服务器端或者从内存中获取,但是没有碰到过实践的机会。直到这次项目的实际需求对我们提出挑战。可见很多知识平时一直只停留在知其然的地方是远远不够的。只有平时多做积累,掌握各种工具,在实际遇到挑战时才能有足够的能力解决问题。
技术要点总结
- 分析内存镜像并判断适用的配置文件(profile)
volatility.exe –f memdump.mem imageinfo
2. 寻找某信进程的pid
volatility.exe –f memdump.mem --profile=Win7SP1x64 pslist >pslist.txt
- 寻找WeChatWin.dll的基址
volatility.exe –f memdump.mem --profile= Win7SP1x64 ldrmodules –p pid of WeChat.exe >dlllist.txt
- 查询某信数据库密钥
volatility.exe –f memdump.mem --profile= Win7SP1x64 volshell
cc(name=”WeChat.exe”)
dd(base address of WeChatWin.dll + fixed offset, length=4)
#返回结果为数据库密钥地址
#常数fixed offset根据某信版本不同可能有所变化。在这里测试所使用的版本为某信2.9.5.41,该常数为“0x17734a8”。
db(address of decryption key, length=32)
#返回结果为数据库密钥