windows取证之导出微信&QQ聊天记录
文章最后更新时间为:2024年03月26日 15:47:25
记录一下windows取证的一些步骤,主要是为了导出windows上的微信&qq的聊天记录,没什么新的东西,把最近实践的过程记录下。
1.微信聊天记录
微信聊天记录存储在sqlite数据库中,但是加密了,所以需要先获取到解密密钥。解密密钥的获取一般都是在内存中,所以需要微信在登录状态下才能获取到。
1.1 获取数据库解密密钥
这里要利用到开源工具https://github.com/AdminTest0/SharpWxDump,需要自己编译
一般情况下,我用vs2022打开项目,会提示当前目标.net版本为4.0,是否需要升级该项目的.net版本,这时候最好别升级,尽可能适配更多的目标环境。安装4.0的运行环境可以参考这篇文章:https://blog.csdn.net/GoodCooking/article/details/125347856
编译选择release、x86即可。
直接运行可以获取到key:
1.2 解密微信数据库
微信数据默认情况下位于C:\Users\xxx\Documents\WeChat Files\
,而聊天记录数据库位于该目录下面的wxid_xxxx\Msg\Multi
。聊天记录文件命名一般是MSG.db,超出240MB会自动生成MSG1.db,以此类推
wxid_xxxxxxxx\Msg\Multi\MSG0.db > 聊天记录
wxid_xxxxxxxx\Msg\Multi\MSG1.db > 聊天记录
wxid_xxxxxxxx\Msg\Multi\MSG2.db > 聊天记录
wxid_xxxxxxxx\Msg\MicroMsg.db > Contact字段 > 好友列表
wxid_xxxxxxxx\Msg\MediaMsg.db > 语音 > 格式为silk
关于更多的数据库描述可以看这个文档https://github.com/xaoyaoo/PyWxDump/blob/master/doc/wx%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%80%E8%BF%B0.md
在上一步获取到解密密钥之后,我们可以直接使用下面的脚本解密聊天记录数据库:
# jiemi.py
from Crypto.Cipher import AES
import hashlib, hmac, ctypes, sys, getopt
SQLITE_FILE_HEADER = bytes('SQLite format 3', encoding='ASCII') + bytes(1)
IV_SIZE = 16
HMAC_SHA1_SIZE = 20
KEY_SIZE = 32
DEFAULT_PAGESIZE = 4096
DEFAULT_ITER = 64000
opts, args = getopt.getopt(sys.argv[1:], 'hk:d:')
input_pass = ''
input_dir = ''
for op, value in opts:
if op == '-k':
input_pass = value
else:
if op == '-d':
input_dir = value
password = bytes.fromhex(input_pass.replace(' ', ''))
with open(input_dir, 'rb') as (f):
blist = f.read()
print(len(blist))
salt = blist[:16]
key = hashlib.pbkdf2_hmac('sha1', password, salt, DEFAULT_ITER, KEY_SIZE)
first = blist[16:DEFAULT_PAGESIZE]
mac_salt = bytes([x ^ 58 for x in salt])
mac_key = hashlib.pbkdf2_hmac('sha1', key, mac_salt, 2, KEY_SIZE)
hash_mac = hmac.new(mac_key, digestmod='sha1')
hash_mac.update(first[:-32])
hash_mac.update(bytes(ctypes.c_int(1)))
if hash_mac.digest() == first[-32:-12]:
print('Decryption Success')
else:
print('Password Error')
blist = [blist[i:i + DEFAULT_PAGESIZE] for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)]
with open(input_dir, 'wb') as (f):
f.write(SQLITE_FILE_HEADER)
t = AES.new(key, AES.MODE_CBC, first[-48:-32])
f.write(t.decrypt(first[:-48]))
f.write(first[-48:])
for i in blist:
t = AES.new(key, AES.MODE_CBC, i[-48:-32])
f.write(t.decrypt(i[:-48]))
f.write(i[-48:])
windows上如果报错没有Crypto,就使用下面的命令安装下:
pip install pycryptodome
运行命令如下:
python3 .\jiemi.py -k 数据库密钥 -d .\MSG0.db
1.3 打开聊天记录
直接使用navicate导入sqllite即可:
可以使用查询语句快速检索如查询带"密码"的聊天记录,同时包含个人消息、群消息等等
SELECT * FROM "MSG" WHERE StrContent like'%密码%'
或者使用可视化的软件也可以查看聊天记录https://github.com/Ormicron/chatViewTool
2. qq聊天记录
qq的数据存储也是通过加密的sqlite,但是和微信不一样的是,qq数据库解密的密钥是会变化的,每次登录时会下发一个密钥,所以这也导致了密钥和数据库是一一对应的。
qq聊天记录文件一般保存在C:\Users\xxxx\Documents\Tencent Files\xxxxxxx\Msg3.0.db
2.1 获取解密密钥并解密数据库
解密密钥的破解可以找到下面几个文章:
- https://bbs.kanxue.com/thread-250509.htm
- https://www.52pojie.cn/thread-1370802-1-1.html
- https://bbs.kanxue.com/thread-266370.html
我们可以直接使用项目https://github.com/Young-Lord/qq-win-db-key来获取解密密钥,在登录时使用frida hook KernelUtil.dll,拿到key之后通过hook解密函数可以直接获取解密之后的db文件。
该脚本运行时需要hook到登录过程,也就是执行要遵守:备份Msg3.0.db
-> 打开 QQ -> python hook.py
-> 登录 -> 得到 key
可以看到解密之后的db文件已经保存在当前目录下面了,可以直接使用navicate打开db文件:
主要的聊天信息记录在MsgContent列里面,但是由于被编码了,所以没法直接看到明文。
2.2 解码MsgContent
上一步虽然数据库已经解密了,但是数据都被编码了,没办法直接看到明文,所以还需要解码一下。
https://github.com/Akegarasu/qmsg-unpacker 这个项目可以用来解码MsgContent,具体用法可以参考example。
我在使用过程中,发现这个example不太友好,大家可以参考下面的example
package main
import (
"database/sql"
"fmt"
"github.com/Akegarasu/qmsg-unpacker/qqmsg"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db, err := sql.Open("sqlite3", "./Msg3.0.db_0_xxxxx.db")
if err != nil {
panic(err)
}
//查询数据
rows, err := db.Query("SELECT * FROM group_xxxxxx")
if err != nil {
panic(err)
}
for rows.Next() {
var time int
var rand int
var senduin int
var msgcontent []byte
var msgDecode string
var info []byte
err := rows.Scan(&time, &rand, &senduin, &msgcontent, &info)
if err != nil {
panic(err)
}
fmt.Printf("time: %+v, rand: %+v,senduin: %+v,msgcontent: %+v,info: %+v\n", time, rand, senduin, msgcontent, info)
msg := qqmsg.Unpack(msgcontent)
fmt.Printf("msg %+v\n", msg)
fmt.Printf("SenderNickname: %s\n", msg.SenderNickname)
fmt.Printf("msg.Header.Time: %+v\n", msg.Header.Time)
msgPrintable := qqmsg.EncodeMsg(msg)
// fmt.Println(msgPrintable)
fmt.Printf("msgPrintable: %+v\n", msgPrintable)
break
}
rows.Close()
db.Close()
}
或者可以使用我编写的python脚本,项目地址为:https://github.com/saucer-man/qq_msg_decode,解码原理就是参考了上面的golang项目,在代码中修改下数据库地址,然后直接运行就行,这个脚本会自动将所有的msgContent
字段解密,并且增加一列DecodedMsg
用于存放明文,代码用gpt转的,有点丑陋,对于数据库比较大的情况下,转换过程会比较缓慢。
下面是https://github.com/saucer-man/qq_msg_decode解码后的数据库:
话说qq数据库信息发送的日期时间有办法解码吗
qq数据库这块有更完整的吗(
只有数据存储文件能不能解密
请问~Documents\Tencent Files\xxxxx\MsgBackup里面的文件有办法解密吗? 手和电脑都换了,留存下来的只有MsgBackup里面的文件,哎
为什么我6000+kb的Msg3.0.db文件,解出来只剩170+kb了。剩下的内容解码是成功的,但是还有那么多去哪儿了。
@111 一般不会,你可以前后对比下
你好!你的项目脚本很棒,但我使用中频繁报错:https://github.com/saucer-man/qq_msg_decode/issues/2
有些表解码了一半就报错停下了。如果再次运行,会跳过解了一半的表,继续解码下面的,前面解了一半的表就永远停工了。
在 github 上稍微改进了一下 qq 的解码代码
现在效率高多了(
可以去看一下 PR
如果有能导出自己聊天记录的工具就好了
这也算是一种方法,就是有点废眼睛
@小T 有喔,兄弟!公众号:忆墨痕,自行了解哈
实测成功。
微信聊天记录分为两种, 一种是在电脑端的缓存, 一种是在电脑上备份的手机聊天数据。
@弹道导弹 嗯你说的是对的
根本没用,想解析电脑上别人的微信的记录是不可以的,显示密码错误,自己的就行,因为那个密钥问题
@二打榜 你没看懂文章意思
大部分的聊天记录不在pc客户端, QQ可以把记录备份到~Documents\Tencent Files\xxxxx\MsgBackup 里面, 有办法解开这个文件夹里的记录吗
@薄荷 手机qq的也可以,github上有相关开源项目
如果需要登陆后才能获得key,那这个解密取证还有啥意义,直接从微信上导出就行了
@也无风雨也无晴 微信怎么导出?导出什么形式?
最新版微信是3.9.2.26,似乎不太好使了,数据库密钥还是可以再内存里dump出来,但是解密数据库的时候各种失败
@一个路过的刚刚下班的安全社畜呢 不会吧,我是昨天测试的,没问题,不过忘记看微信版本了
@yanq 你试试这个版本?
@一个路过的刚刚下班的安全社畜呢 这个支持 https://github.com/SpenserCai/GoWxDump
@一个路过的刚刚下班的安全社畜呢 ......
@yanq 我发现问题所在了,这些网上流传的解密方法仅对微信默认的路径下的聊天记录文件生效,我的微信是自己改了聊天文件存储位置的,反而解密不出来,不得不说这是一种自我防御方法哈哈哈哈,听说使用聊天备份工具存储的数据也是同样解密不出来,同样在3.9.2.26下,把微信删了重新安装,使用默认的聊天记录存储路径,这样就能顺利的把数据库文件解密,学到了没有卵用的知识了