记一次微信PC端小程序的逆向

发布于 2021-04-14  1105 次阅读


前提说明

PC端小程序的包有加密,需要解密后才能解包。

环境

解包步骤

  1. 目标小程序为一起学党史,图标如下
    file
  2. 进入文档\WeChat Files文件夹,找到你wxid的那个文件夹,如wxid_abcdefghijkl21,进入文档\WeChat Files\你滴wxid\Applet文件夹,找到小程序wxid的那个文件夹,记住小程序wxid,如wx6e24c691f9a50e44,找法个人觉得有两种比较好:
    • 挨个进入文档\WeChat Files\你滴wxid\Applet\小程序滴wxid\store\images文件夹,看里面存的图片(无后缀,实际格式的话pngjpg都有),有你要找的小程序的贴图或者图标就是了
    • 删除除了global外的小程序文件夹,然后重新打开一下小程序,看看蹦出来的文件夹是哪个(没测试过行不行)
  3. 进入文档\WeChat Files\Applet\小程序滴wxid\可能是版本号文件夹,拿到__APP__.wxapkg,可能还会有分包文件,本文不作讨论(主要是我没用上)
  4. 命令行使用pc_wxapkg_decrypt_python解密小程序包
    python main.py --wxid 小程序滴wxid --file __APP__.wxapkg --output 解密后的文件名.wxapkg
  5. 使用mp-unpack解包小程序包

网络数据包验签分析

本文目标案例的小程序每个数据包都带了sign字段,长度40,猜测可能是sha1哈希。

file

查找文本发现如下可疑代码段。

file

function getsign2(params) {
    var s_data = "";
    var keys = [];
    for (var key in params) {
        if (params.hasOwnProperty(key)) {
            var value = params[key];
            keys.push(key);
        }
    }
    var arr = [];
    keys.sort();
    for (var i = 0; i < keys.length; i++) {
        var k = keys[i];
        var v = params[k];
        arr.push(k + "=" + v);
    }
    s_data = arr.join("&");
    var sign = sha1(SparkMD5.hash(s_data) + "lanzu@123");
    params.sign = sign;
    return params;
}

直接控制台构造一个params进行模拟测试,看看是不是和抓到的数据包一样。

file

因为控制台不好导加密包,所以直接拿这一串去sha1(md5(s_data)+'lanzu@123')

得到结果发现与抓包结果一样。

file

直接python还原一下生成验签的步骤。

def sign(params: dict) -> dict:
    keys = list(params.keys())
    keys.sort()
    s_data = "&".join([f'{key}={params[key]}' for key in keys])
    sign = sha1(f'{md5(s_data.encode()).hexdigest()}lanzu@123'.encode()).hexdigest()
    params['sign'] = sign
    return params

The End