目录

简介

小程序(Mini Program)17 年提出,多见于工具应用,如健康码,打开就用,用完就关。小程序前端技术和前端框架一样,也是 MVVM 模式开发,后端由其他服务提供数据。

利用

微信官方给出开发原则,看完大概就能清楚常遇到的安全测试项有哪些。

  1. 互不信任原则,不要信任用户提交的数据,包括第三方系统提供的数据,必要的数据校验必须放在后台校验。
  2. 最小权限原则,代码、模块等只拥有可以完成任务的最小权限,不赋予不必要的权限。
  3. 禁止明文保存用户敏感数据。
  4. 小程序代码(不包括云函数代码)跟传统 Web 应用的前端代码类似,可被外部获取及进行反混淆,重要业务逻辑应放在后台代码或云函数中进行。
  5. 后台接口调用以及云函数调用,必须进行有效的身份鉴权。

https://developers.weixin.qq.com/miniprogram/dev/framework/security.html#开发原则与注意事项

小程序信息收集

小程序更多资料面板。

  • 开发者:可以通过公司名称来识别资产属于谁管理。
  • AppID:通过小程序 ID 能够找到包的路径。
  • 服务及数据由以下网址提供:所有请求都指向列出的域名。

“服务及数据由以下网址提供”板块可以编写脚本获取收集域名扩大攻击面:

  1. 通过名称快速获取所有 AppID。
  2. 通过 AppID 查询 “服务及数据由以下网址提供” 。

微信小程序信息.jpg

支付宝小程序和微信没差别,“关于” 就多了个客服电话。

支付宝小程序信息.jpg

整体思路是通过关键字快速获取目标相关小程序,再从这些公开信息提取域名。

寻找小程序包

Windows

通过 ICON 确认小程序 ID

手机上打开微信小程序在 PC 端查看。

PC 端查看移动端正在浏览的小程序.png

找到微信安装目录。

打开微信安装目录.png

打开 D:\WeChat\Document\WeChat Files\wxid_XXXXXX,有个 account_wechatID 文件夹是微信账户目录。

打开微信安装目录2.png

PC 上打开第一次打开小程序会创建新目录,目录名为小程序 ID,通过日志更新日期确定就是正在浏览的小程序。

小程序存放目录.png

防止认错,看 ICON 交叉比较。

查看小程序 ICON 交叉验证.png

通过小程序资料获取 ID

小程序资料.jpg

解密 Windows 小程序包

有了小程序 ID,需要到其下载目录 D:\WeChat\Document\WeChat Files\Applet 的包找以 ID 命名的目录。__APP__.wxapkg 为打包好的文件。

小程序包具体目录.png

Windows 小程序使用 GitHub - kksanyu/pc_wxapkg_decrypt_python: PC微信小程序 wxapkg 解密 解密后续才能解包审计。工具第一次使用需要安装库 Python3 库。

pip install pycryptodome Crypto

防止工具消失,备份对应源码。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import argparse
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA1
from Crypto.Cipher import AES

# 微信小程序包 自定义标识
WXAPKG_FLAG = 'V1MMWX'
WXAPKG_FLAG_LEN = len(WXAPKG_FLAG)

def main():

    parser = argparse.ArgumentParser(description='PC微信小程序wxapkg包解密工具')
    parser.add_argument('--wxid', metavar='微信小程序ID', required=True)
    parser.add_argument('--iv', metavar='iv', required=False, default='the iv: 16 bytes')
    parser.add_argument('--salt', metavar='salt', required=False, default='saltiest')
    parser.add_argument('-f', '--file', metavar='加密的小程序包文件路径', required=True)
    parser.add_argument('-o', '--output', metavar='解密后的小程序包文件路径', required=True)

    args = parser.parse_args()

    key = PBKDF2(args.wxid.encode('utf-8'), args.salt.encode('utf-8'), 32, count=1000, hmac_hash_module=SHA1)

    # 读取加密的内容
    if not os.path.exists(args.file):
        raise Exception('文件不存在')

    with open(args.file, mode='rb') as f:
        dataByte = f.read()

    if dataByte[0:WXAPKG_FLAG_LEN].decode() != WXAPKG_FLAG:
        raise Exception('该文件无需解密, 或者不是微信小程序wxapkg加密包')

    # 初始化密钥
    cipher = AES.new(key, AES.MODE_CBC, args.iv.encode('utf-8'))

    # 解密头部1024个字节
    originData = cipher.decrypt(dataByte[WXAPKG_FLAG_LEN: 1024 + WXAPKG_FLAG_LEN])

    # 初始化xor密钥, 解密剩余字节
    xorKey = 0x66
    if len(args.wxid) >= 2:
        xorKey = ord(args.wxid[len(args.wxid) - 2])

    afData = dataByte[1024 + WXAPKG_FLAG_LEN:]

    out = bytearray()
    for i in range(len(afData)):
        out.append(afData[i] ^ xorKey)

    originData = originData[0:1023] + out

    # 保存解密后的数据
    with open(args.output, mode='wb') as f:
        f.write(originData)

    print('解密成功', args.output)

if __name__ == "__main__":
    main()

Android(待补充)

实体机需要 Root,因此使用模拟器即可。

macOS(待补充)

IOS(待补充)

需要越狱,较为麻烦。

解包审计

解包工具使用 mp-unpack。这里给出下载备份 mp-unpack Setup 1.1.2.exe

点击解主包时会把卡密发到 http://cloud.xuedingmiao.com/unpack-client?s=run&wxapp_id=10004&card_no=123 检测 card_no 值,不存在返回 {"code":0,"msg":"当前卡密不存在!","data":[]},客户端判断 code 值确定激活状态,将 code 改为 1 可以绕过卡密检测。

客户端会员检测绕过.png

下载微信小程序开发者工具,导入解密的项目。

微信小程序开发者工具.png

使用过程中遇到 “不支持打开非业务域名”。

不支持打开非业务域名报错.png

需要关闭域名检查。

启用不校验合法域名.png

挂代理做常规 Web 测试

开发者工具

直接就在开发者工具的模拟器面板操作即可,将所有请求发送到 BurpSuite。

微信小程序开发者工具设置代理1.png
微信小程序开发者工具设置代理2.png

Proxifer 转发

移动端打开小程序,在电脑上打开。

确认小程序应用路径.png

使用任务管理器找到小程序应用目录。

任务管理器打开微信小程序目录.png

设置代理服务器。

ProxyServers设置代理服务器.png

设置规则。

ProxyServers 设置流量转发规则.png

小程序 AppSecret 泄露(待补充)

有了 AppSecret 可以联合 AppID 获取 access_token 直接控制小程序。

如何获取 Token。

可以用调试工具
https://mp.weixin.qq.com/debug/cgi-bin/apiinfo,或者向接口发 GET 请求。

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

access_token 使用限制

Token 有效期为 2 小时。

access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;

https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html#:~:text=invalid%20appid%22%7D-,access_token%20%E7%9A%84%E5%AD%98%E5%82%A8%E4%B8%8E%E6%9B%B4%E6%96%B0,-access_token

默认情况每天只能获取 2000 次。

access_token每日上限获取次数.png

Token 白名单限制。当新账户要获取 access_token 必须配置白名单 IP,不然会返回 -1000 系统错误状态码。

200 OK
Connection: close
Date: Mon, 25-Jul-2022 07:14:41 GMT
Content-Type: application/json; encoding=utf-8
Content-Length: 46

{
    "errcode": -1000, 
    "errmsg": "system error"
}

access_token 后续利用,可以用发送图文文章/消息用于钓鱼。

小程序 CSRF(待补充)

查看参考链接“微信小程序的渗透五脉”一文。

参考链接

最近更新:

发布时间:

讨论讨论

Asia/Shanghai