BeneficialWeb 发表于 2024-1-18 14:39

WeChat MsgDb Decrypt

# WeChat MsgDb Decrypt

# 提取数据库

```csharp
ls /data/data/com.tencent.mm/MicroMsg/21159b1820fe6ca555bfa51a3675b28d/EnMicroMsg.db
adb root
adb pull /data/data/com.tencent.mm/MicroMsg/21159b1820fe6ca555bfa51a3675b28d/EnMicroMsg.db
adb pull /sdcard/Download/EnMicroMsg.db
```

PAGE_SIZE: 1024

KDF iteratorations: 4000

HMAC algorithm: sha1

KDF algorithm: sha1

pysqlcipher3的解密数据库的实现如下,由于该库的编译过程过于复杂,且`pip install pysqlcipher3` 在python3上无法直接安装,予以放弃,采取自实现解密。

```python
              conn = sqlite.connect(in_db_path)
      c = conn.cursor()
      c.execute("PRAGMA key = '" + passwd + "';")
      c.execute("PRAGMA cipher_use_hmac = OFF;")
      c.execute("PRAGMA kdf_iter = 4000;")
      c.execute("PRAGMA cipher_page_size = 1024;")
      c.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA1;")
      c.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;")
      c.execute("ATTACH DATABASE '" + out_db + "' AS db KEY '';")
      c.execute("SELECT sqlcipher_export('db');")
      c.execute("DETACH DATABASE db;")
      conn.close()
```

(https://sqlitebrowser.org/dl/)

# 安装frida

```python
pip install frida
pip install frida-tools
pip install objection
adb push frida-server-16.1.10-android-arm64 /data/local/tmp/frida-server
cd /data/local/tmp
chmod 777 frida-server
./frida-server
```

frida unexpected response: PasswordProtected

拔掉其他手机设备

hook相关函数,打印参数用于验证密钥生成算法是否正确。

```python
frida-ps -U -a
objection -g com.tencent.mm explore
android hooking list class_methods com.tencent.wcdb.database.SQLiteDatabase
android hooking watch class_method com.tencent.wcdb.database.SQLiteDatabase.open --dump-args
```

# HMAC

```c
if this context is setup to use hmac checks, generate a seperate and different
key for HMAC. In this case, we use the output of the previous KDF as the input to
this KDF run. This ensures a distinct but predictable HMAC key.

```

sqlcipher_codec_pragma

```python
static int sqlcipher_codec_ctx_reserve_setup(codec_ctx *ctx) {
int base_reserve = ctx->iv_sz; /* base reserve size will be IV only */
int reserve = base_reserve;

ctx->hmac_sz = ctx->provider->get_hmac_sz(ctx->provider_ctx, ctx->hmac_algorithm);

if(sqlcipher_codec_ctx_get_use_hmac(ctx))
    reserve += ctx->hmac_sz; /* if reserve will include hmac, update that size */

/* calculate the amount of reserve needed in even increments of the cipher block size */
if(ctx->block_sz > 0) {
    reserve = ((reserve % ctx->block_sz) == 0) ? reserve :
               ((reserve / ctx->block_sz) + 1) * ctx->block_sz;
}

sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipher_codec_ctx_reserve_setup: base_reserve=%d block_sz=%d md_size=%d reserve=%d",
                base_reserve, ctx->block_sz, ctx->hmac_sz, reserve);

ctx->reserve_sz = reserve;

return SQLITE_OK;
}
```

第一页

PAGE_SIZE - SALT_SIZE - RESERVE_SIZE

1024 - 16 - 16 = 992

992/16 = 62

后续页

PAGE_SIZE - RESERVE_SIZE

1024-16 = 1008

1008/16 = 63

auth_info_key_prefs.xml

EnMicroMsg.db

由于无hmac验证,根据sqlcipher_codec_ctx_reserve_setup算法可知预留大小发生变化。

# 形成解密脚本

```python
import os
from typing import Union,List
from Crypto.Cipher import AES
import hashlib
import hmac
import binascii
import sqlite3

SQLITE_FILE_HEADER = b"SQLite format 3\x00"

KEY_SIZE = 32
DEFAULT_PAGESIZE = 1024
DEFAULT_ITER = 4000

# 通过密钥解密数据库
def decrypt(key: str, db_path, out_path):
    """
    通过密钥解密数据库
    :param key: 密钥 7位16进制字符串
    :param db_path:待解密的数据库路径(必须是文件)
    :param out_path:解密后的数据库输出路径(必须是文件)
    :return:
    """
    if not os.path.exists(db_path) or not os.path.isfile(db_path):
      raise Exception("db_path must be a file")

    with open(db_path,"rb") as file:
      blist = file.read()

    # 每一个数据库文件的开头16字节都保存了一段唯一且随机的盐值,作为HMAC的验证和数据的解密
    salt = blist[:16]
    byteKey = hashlib.pbkdf2_hmac('sha1',key.encode(),salt,DEFAULT_ITER,dklen=KEY_SIZE)
    first = blist
    if len(salt) != 16:
      raise Exception("salt must be 16 bytes")

    block_sz = 16

    reserve_sz = 0
    # iv size
    iv_sz = 16
    # hmac size
    hmac_sz = 20

    reserve_sz = iv_sz
    reserve_sz += hmac_sz
    if reserve_sz % block_sz != 0:
      reserve_sz = ((reserve_sz // block_sz) + 1) * block_sz
    print("reserve_sz:",reserve_sz)

    reserve_sz = iv_sz
    if reserve_sz % block_sz != 0:
      reserve_sz = ((reserve_sz // block_sz) + 1) * block_sz

    print("reserve_sz:",reserve_sz)

    newblist = for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)]

    with open(out_path,"wb") as deFile:
      deFile.write(SQLITE_FILE_HEADER)
      # 第一页前16字节为盐值,紧接着是992字节的加密数据段和16字节的保留段
      iv = first[-16:]
      t = AES.new(byteKey, AES.MODE_CBC, iv)
      decrypted = t.decrypt(first[:-16])
      deFile.write(decrypted)
      deFile.write(first[-16:])

      # 后续页均是1008字节长度的加密数据段和16字节的保留段
      for i in newblist:
            iv = i[-16:]
            t = AES.new(byteKey, AES.MODE_CBC, iv)
            decrypted = t.decrypt(i[:-16])
            deFile.write(decrypted)
            deFile.write(i[-16:])
   
    return True,

def get_msgdb_key(uin,imei):
    key = imei + uin
    md5 = hashlib.md5()
    md5.update(key.encode('utf-8'))
    key = md5.hexdigest()[:7].lower()
    print("key:",key)
    return key

def parse_contract(db_path):
    if not os.path.exists(db_path):
      print("DB not found: ", db_path)
      return False
    conn = sqlite3.connect(db_path)
    c = conn.cursor()
    users = c.execute("SELECT username, alias, nickname from rcontact WHERE type=1 OR type=8388611")
    for user in users:
      username = user
      alias = user
      nickname = user
      # 忽略微信团队和文件助手
      if username == "weixin" or username == "filehelper":
            continue
      print(user)
    return True

imei = "1234567890ABCDEF"
uin = "1146048721"
key = get_msgdb_key(uin,imei)

ret = decrypt(key,"EnMicroMsg.db","EnMicroMsg.decrypted.db")

parse_contract("EnMicroMsg.decrypted.db")
```

(https://github.com/BeneficialCode/wechat_msgdb_decrypt)

ericzhao666 发表于 2024-1-21 00:04

厉害。大佬对微信这块是否很熟悉?我这边有一个问题想咨询,有没有可能在领取红包之前就能获取到红包总金额和其他人的领取金额?之前确定是能实现的,但已失效。想知道现在是否可以实现,大概思路什么样

EnterpriseSolu 发表于 2024-1-20 22:29

厉害啊,人狠话不多,几句话,几个步骤,手起刀落,揭开数据秘密,这个功能,有个应用场景,手机里最讨厌wechat的文件夹,巨大,又不敢随便删除,有 这个工具,我可以随便动动,不过就是几个数据文件

topshot 发表于 2024-1-18 17:51

解密这个感觉作用不大

alan3258 发表于 2024-1-18 17:59

貌似,应用范围不是太多吧

losingstars 发表于 2024-1-18 20:38

有成果展示吗?

yanaying 发表于 2024-1-18 21:22

试过2G以上的微信数据库吗

cnfeitian 发表于 2024-1-19 06:31

这个是解密微信数据库么?

FBIleon 发表于 2024-1-19 08:38

这个是起什么作用的?

wind315_ 发表于 2024-1-19 09:42

TX马上升级encrypt算法

wind315_ 发表于 2024-1-19 09:47

完全看不明白,请问楼主基础知识需要哪些?

top777 发表于 2024-1-19 10:17

赶紧保存,此贴估计活不过24小时。
页: [1] 2 3
查看完整版本: WeChat MsgDb Decrypt