windows取证之导出微信&QQ聊天记录

文章最后更新时间为:2023年06月01日 14:01:38

记录一下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即可。

2023-05-30T07:49:17.png

直接运行可以获取到key:

2023-05-30T07:50:16.png

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

2023-05-30T07:53:14.png

在上一步获取到解密密钥之后,我们可以直接使用下面的脚本解密聊天记录数据库:

# 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

2023-05-30T07:57:25.png

1.3 打开聊天记录

直接使用navicate导入sqllite即可:

2023-05-30T07:59:44.png

可以使用查询语句快速检索如查询带"密码"的聊天记录,同时包含个人消息、群消息等等

SELECT * FROM "MSG" WHERE StrContent  like'%密码%'

2. qq聊天记录

qq的数据存储也是通过加密的sqlite,但是和微信不一样的是,qq数据库解密的密钥是会变化的,每次登录时会下发一个密钥,所以这也导致了密钥和数据库是一一对应的。

qq聊天记录文件一般保存在C:\Users\xxxx\Documents\Tencent Files\xxxxxxx\Msg3.0.db

2.1 获取解密密钥并解密数据库

解密密钥的破解可以找到下面几个文章:

我们可以直接使用项目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

2023-06-01T03:26:37.png

可以看到解密之后的db文件已经保存在当前目录下面了,可以直接使用navicate打开db文件:

2023-06-01T03:31:01.png

主要的聊天信息记录在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解码后的数据库:

2023-06-01T06:01:20.png

1 + 5 =
19 评论
    111 Chrome 120 Windows 10
    1月11日 回复

    为什么我6000+kb的Msg3.0.db文件,解出来只剩170+kb了。剩下的内容解码是成功的,但是还有那么多去哪儿了。

      saucerman Chrome 120 Windows 10
      1月12日 回复

      @111 一般不会,你可以前后对比下

    和月清岚 Chrome 120 Windows 10
    2023年12月20日 回复

    你好!你的项目脚本很棒,但我使用中频繁报错:https://github.com/saucer-man/qq_msg_decode/issues/2
    有些表解码了一半就报错停下了。如果再次运行,会跳过解了一半的表,继续解码下面的,前面解了一半的表就永远停工了。

    shenjack Chrome 119 Windows 10
    2023年11月19日 回复

    在 github 上稍微改进了一下 qq 的解码代码
    现在效率高多了(
    可以去看一下 PR

    小T Chrome 116 Windows 10
    2023年09月09日 回复

    如果有能导出自己聊天记录的工具就好了
    这也算是一种方法,就是有点废眼睛

    弹道导弹 Chrome 116 OSX
    2023年09月01日 回复

    实测成功。
    微信聊天记录分为两种, 一种是在电脑端的缓存, 一种是在电脑上备份的手机聊天数据。

    1. 电脑上备份的手机聊天数据, 无法解密。
    2. 电脑上缓存的聊天数据, 可以解密,但是一般手机登陆电脑微信,也只能缓存最近几天的数据,除非你每天登陆,每天同步,那你电脑微信缓存的数据,基本上就是全部数据, 全部可以解密
      saucerman Chrome 114 OSX
      2023年09月01日 回复

      @弹道导弹 嗯你说的是对的

    二打榜 Chrome 90 Android 12
    2023年08月21日 回复

    根本没用,想解析电脑上别人的微信的记录是不可以的,显示密码错误,自己的就行,因为那个密钥问题

      saucerman Chrome 116 Windows 10
      2023年08月24日 回复

      @二打榜 你没看懂文章意思

    薄荷 Chrome 116 Windows 10
    2023年08月21日 回复

    大部分的聊天记录不在pc客户端, QQ可以把记录备份到~Documents\Tencent Files\xxxxx\MsgBackup 里面, 有办法解开这个文件夹里的记录吗

      saucerman Chrome 116 Windows 10
      2023年08月24日 回复

      @薄荷 手机qq的也可以,github上有相关开源项目

    也无风雨也无晴 Chrome 112 OSX
    2023年08月10日 回复

    如果需要登陆后才能获得key,那这个解密取证还有啥意义,直接从微信上导出就行了

      saucerman Chrome 115 Windows 10
      2023年08月11日 回复

      @也无风雨也无晴 微信怎么导出?导出什么形式?

    一个路过的刚刚下班的安全社畜呢 Chrome 113 Windows 10
    2023年06月01日 回复

    最新版微信是3.9.2.26,似乎不太好使了,数据库密钥还是可以再内存里dump出来,但是解密数据库的时候各种失败

      saucerman Chrome 113 Windows 10
      2023年06月02日 回复

      @一个路过的刚刚下班的安全社畜呢 不会吧,我是昨天测试的,没问题,不过忘记看微信版本了

        一个路过的刚刚下班的安全社畜呢 Chrome 113 Windows 10
        2023年06月02日 回复

        @saucerman 你试试这个版本?

          saucerman Chrome 113 Windows 10
          2023年06月07日 回复
            saucerman Chrome 114 Windows 10
            2023年06月07日
            一个路过的刚刚下班的安全社畜呢 Chrome 114 Windows 10
            2023年06月07日

            @saucerman 我发现问题所在了,这些网上流传的解密方法仅对微信默认的路径下的聊天记录文件生效,我的微信是自己改了聊天文件存储位置的,反而解密不出来,不得不说这是一种自我防御方法哈哈哈哈,听说使用聊天备份工具存储的数据也是同样解密不出来,同样在3.9.2.26下,把微信删了重新安装,使用默认的聊天记录存储路径,这样就能顺利的把数据库文件解密,学到了没有卵用的知识了