0x00 前言
本次任务是找到微信聊天的本地数据库文件,提取数据库中特定聊天对象的XML格式的消息,格式化消息并保存到本地。
0x01 环境
- 本次任务中所用到的工具有:VSCODE(编写Python),DB Browser for SQLite(处理加密的数据库)
系统信息:MacOS Big Sur 11.1
微信版本:Version. 2.6.1 (16853)
🔗下载链接:DB Browser for SQLite(https://github.com/sqlitebrowser/sqlitebrowser/releases/tag/v3.12.1)
0x02 找到本地数据的位置
- Mac微信聊天文件目录:
~/library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/
- 图中的DB文件就是,加密的数据库文件,可以根据文件最后的修改日期来选择目标数据库,本次任务的目标数据库是图中的msg_4.db
⚠️注意:本地聊天数据库的密码可以用下面的方法得到,但是从手机备份的聊天数据库的密码可能不能够用本方法得到,我尝试了一下,没有成功,各位可以自行尝试。
0x03 提取数据的密码
请参照文章来操作:
我介绍一下这个过程遇到的坑:
1.打开db为后缀的文件
2.密码选择原始密钥
3.代码尽量复制😂
0x04 找到目标通信记录
- 进入数据库后选择浏览数据,并且更换不同的数据表,一个联系人就是一个表
- 经过一番查找最终找到了目标聊天记录
- 对于普通的聊天记录可以用SQL语句进行操作,全选查询后的列表,复制即可,值得注意的是转发消息的内容是XML格式的一堆东西
SELECT msgContent From Chat_ff5f08e3**********(目标数据表)
- 本次的目标数据是转发的数据,将文本数据拷贝下来放入Python处理XML格式一坨代码,从中提取到目标信息
0x05 Python格式化代码
分析XML代码发现:
- <title></title>包裹的是聊天的标题
- <des></des>包裹的是聊天的摘要
- <recorditem></recorditem>包裹的是聊天的所有内容,包括时间,消息类型等信息
- <datadesc></datadesc>包裹的是单条消息,这个是最值得我们关注的,其中的<和>为转义字符“<”和“ >”
- #&#x0A;为换行符
- &#x20;为空格
设计脚本的算法
- 任务目标:读取本地保存的SQL中XML文件,将<datadesc></datadesc>包裹的单条消息取出,写入到桌面上的WeChatFile.txt文件中,要求每条消息都要间隔开
- 分解目标:
1.读取本地保存的XML格式的TXT文件
2.取聊天的内容,即取出<recorditem></recorditem>包裹的内容到temp
3.以消息起始符<datadesc>分割temp,得到消息队列chatGroup
4.对chatGroup的有效成员(第0号抛弃,从1开始),进行格式化,取消息结束符</datadesc>前面的内容,将转移字符进行替换为空格或者换行符,并将处理好的单条消息chatItem放入队列chatItems
5.将chatItems打印或者写入文件
Python所实现的代码
#coding:utf-8
#date:2021/1/31
#function:读取本地保存的SQL中XML文件,将<datadesc></datadesc>包裹的单条消息取出,写入到桌面上的WeChatFile.txt文件中,要求每条消息都要间隔开
chatItems = [] #处理好的单条消息放入此数组
fileName = "/Users/wangsen/Desktop/WeChatFlie.txt" #最后存放Txt的路径
targetFlie = "/Users/wangsen/Desktop/l.txt" #存放一坨XML的路径
# 读入文件
tr = open(targetFlie,'r')
contents = tr.read()
tr.close()
# -------
# 取出<recorditem></recorditem>包裹的内容到temp
temp = contents.split('<recorditem>')
temp = temp[1].split('</recorditem>')
# -------------------------------------------
chatGroup = temp[0].split('<datadesc>') #以消息起始符<datadesc>分割temp,得到消息队列chatGroup
# 对chatGroup的有效成员(第0号抛弃,从1开始),进行格式化
for i in range(1,len(chatGroup)):
temp = chatGroup[i].split('</datadesc>') # 取消息结束符</datadesc>前面的内容,
chatItem = temp[0].replace('
', '\r\n') # 将转移字符进行替换为空格或者换行符
chatItem = chatItem.replace(' ', ' ')
chatItems.append(chatItem) #并将处理好的单条消息chatItem放入队列chatItems
# ------------------------------------------------
# 将chatItems打印或者写入文件
f = open(fileName, 'w')
for i in range(0, len(chatItems)):
f.write(chatItems[i])
f.write("\r\n") #插入换行符
f.write("\r\n") #插入换行符
f.close()
# -------------------------
- 最终效果图:
0x06 后记
本文参考以下文章:
- No Pains,No Gains!