吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4421|回复: 26
收起左侧

[Android 原创] WeChat MsgDb Decrypt

[复制链接]
BeneficialWeb 发表于 2024-1-18 14:39

WeChat MsgDb Decrypt

提取数据库

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上无法直接安装,予以放弃,采取自实现解密。

        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

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相关函数,打印参数用于验证密钥生成算法是否正确。

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

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

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算法可知预留大小发生变化。

形成解密脚本

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[16:DEFAULT_PAGESIZE]
    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 = [blist[i:i + DEFAULT_PAGESIZE] 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,[db_path,out_path]

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[0]
        alias = user[1]
        nickname = user[2]
        # 忽略微信团队和文件助手
        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

免费评分

参与人数 6威望 +1 吾爱币 +25 热心值 +5 收起 理由
eetoo + 1 谢谢@Thanks!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
小小超 + 1 + 1 谢谢@Thanks!
willgoon + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
尹铭 + 1 + 1 膜拜
梦入神机 + 2 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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小时。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 09:16

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表