Skip to main content

wechat-miniprogram-pentesting

微信小程序渗透测试方法论。覆盖 .wxapkg 解包与源码还原、前端代码审计(密钥硬编码/接口清单/加密逻辑)、接口越权(客户端可控状态位/ID 遍历/水平越权)、支付与业务逻辑、本地存储与 WebView、云开发与开放数据接口。当拿到小程序反编译产物、.wxapkg 包、AppID 或 #小程序:// 短链,需要测试其安全性时使用。

Datos de origen

Repositorio
wgpsec/AboutSecurity
Última actividad en el origen
16 de octubre de 2026 a las 03:18
Idioma detectado de SKILL.md
chino
Estrellas
1807
Forks
250

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
3 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
wechat-miniprogram-pentesting
description
微信小程序渗透测试方法论。覆盖 .wxapkg 解包与源码还原、前端代码审计(密钥硬编码/接口清单/加密逻辑)、接口越权(客户端可控状态位/ID 遍历/水平越权)、支付与业务逻辑、本地存储与 WebView、云开发与开放数据接口。当拿到小程序反编译产物、.wxapkg 包、AppID 或 #小程序:// 短链,需要测试其安全性时使用。
metadata
{"tags":"wechat,miniprogram,wxapkg,小程序,appid,小程序安全,wxml,反编译,接口越权,支付逻辑","category":"mobile"}
# 微信小程序渗透测试方法论 > **阶段流**: 确认手上有什么 → 获取客户端产物 → 解包还原 → 源码审计 → 接口面测试 → 授权与支付逻辑 → 输出 ## 深入参考 - .wxapkg 解包、分包合并与还原失败排查 → [references/wxapkg-unpacking.md](references/wxapkg-unpacking.md) - 前端源码审计要点与密钥/接口提取模式 → [references/miniprogram-source-audit.md](references/miniprogram-source-audit.md) --- ## Phase 0: 先确认手上有什么 小程序测试的第一个分岔不是技术,而是**目标产物的来源**。必须先确认起点,不要凭 AppID 在本地文件系统里盲目搜索——容器或测试机上大概率根本没有目标产物,找不到不代表包不存在。 ``` 手上有哪一类产物? ├─ 已反编译的源码目录/压缩包 → 直接进 Phase 2(最高效,跳过解包) ├─ .wxapkg 包文件 → 进 Phase 1 解包 ├─ AppID 或 #小程序:// 短链 → 进 Phase 3,仅能做接口面测试 └─ 什么都没有 → 停止本地搜索,向操作员索取(见下方「产物获取」) ``` ### 产物获取(缺产物时) 不要在没有产物的情况下继续执行。应向操作员说明需要什么,并给出获取路径: | 目标产物 | 获取方式 | |----------|----------| | `.wxapkg` 包 | Android 设备上小程序运行后,包缓存在微信私有目录(需 root 或 adb 备份);PC 端微信同样有缓存目录 | | 已解包源码 | 操作员用任意解包工具处理 `.wxapkg` 后直接提供压缩包 | | AppID | 小程序详情页「更多资料」,或抓包看到的请求参数 | | 接口流量 | 操作员在用小程序时配合抓包工具导出的会话文件 | AppID 是 18 位、`wx` 开头的十六进制串(`wx` + 16 位 hex)。`#小程序://` 是 PC 端分享短链,需要用微信打开一次才能拿到真实包与流量。 ### 边界前提 - 只处理**已获授权**的小程序。解包与审计产物按授权范围处理,不外传、不公开。 - 小程序的前端产物**全部是客户端可控内容**。任何"前端做了校验"的假设都不成立,所有鉴权与业务规则必须在服务端复核。 --- ## Phase 1: 解包 .wxapkg `.wxapkg` 是微信小程序的编译产物容器:包头的魔数、文件表、数据段都是自定义二进制格式,`unzip` 之类工具打不开。 ```bash # 基本用法:解包单个包,输出到同名目录 wxapkg ./app.wxapkg # 分包:以主包目录为基准合并 wxapkg -s=./main ./sub-package.wxapkg # 只解包、不做资源还原(用于判断问题出在包还是还原阶段) wxapkg -o ./app.wxapkg # 批量 wxapkg -f ./*.wxapkg ``` 解包后得到的是编译产物与还原后的资源:`.js`(美化后的逻辑)、`.wxml`(模板)、`.wxss`(样式)、`.json`(配置与分包信息)。 **还原不是无损反编译**:小程序编译格式随微信版本变化,部分新格式可能处理不干净。若还原报错或产出可疑,先用 `-o` 只解包原始文件,确认包本身能被读取,再区分问题属于包加密、包格式还是还原阶段。详细排查见 [references/wxapkg-unpacking.md](references/wxapkg-unpacking.md)。 **遇到加密包**:小程序包可能被加固/加密,此时解包会直接报魔数错误。这不是姿势问题,需要操作员提供相应的解包环境或已解包产物,不要在容器里尝试爆破或绕过。 --- ## Phase 2: 前端源码审计 拿到源码后,小程序前端与一个普通 Web 前端没有本质区别。审计目标不是"找漏洞",而是**画出攻击面地图**:哪些接口、哪些参数、哪些在客户端可控。 ### 高价值目标清单 | 类别 | 位置 | 关注点 | |------|------|--------| | 密钥与凭据 | `.js` 全局常量、`config` 类文件 | AppSecret、云开发密钥、地图/短信三方 key、加密 IV | | 接口清单 | `request` 调用点、`app.js` 的 baseUrl | 接口路径、方法、参数名、是否需要登录态 | | 加密实现 | 自写的 `encrypt` / `sign` 函数 | 密钥是否硬编码、签名是否可离线伪造 | | 权限判断 | 页面 `onLoad` 里的 if 分支 | 是否有"客户端判断角色"的逻辑 | | 本地存储 | `wx.setStorage` / `getStorage` | 存了什么、是否存角色或权限标记 | | 业务规则 | 价格、折扣、次数限制计算 | 是否在客户端算完直接提交服务端 | 审计模式与提取命令见 [references/miniprogram-source-audit.md](references/miniprogram-source-audit.md)。 ### 客户端可控状态位(高频根因) 小程序里最常见的越权根因,是**服务端信任了客户端传来的状态或身份字段**。典型形态:前端在本地存一个角色/身份标记,请求时带上,服务端据此返回数据而不做服务端鉴权。 审计时按这个思路找: ``` 搜索这类字段名 → 找请求里谁携带它 → 尝试改成其他值 → 看响应是否变化 role / isAdmin / userType / level / identity / statenow / storeId / tenantId ``` **这类字段一律视为客户端可控**,只要能改就必须实测服务端是否复核。发现后不要只报"前端有角色字段",要实际改值发请求,用响应差异证明越权成立。 --- ## Phase 3: 接口面测试 小程序的所有业务都通过接口完成,接口面是产出最稳定的方向。 ### 鉴权边界 拿到接口清单后,先确定三个问题: 1. **哪些接口不需要登录态**?去掉 token/Cookie 重放,能通的接口直接从 Phase 2 的"需要登录"清单里独立出来。 2. **登录态怎么校验**?是自己签发的 token 还是微信 `code` 换取的会话?签发逻辑可预测就能伪造。 3. **越权方向**:横向(换个用户 ID 拿别人的数据)、纵向(普通用户调管理接口)。 ### 变更类接口优先 只读接口的越权危害有限,优先测**会改状态或动钱的接口**:下单、改地址、退款、核销、加积分、改权限。这类接口一旦信任客户端参数,危害直接可证。 ### 参数遍历 ID 类参数(`orderId`、`userId`、`couponId`、`storeId`)逐个替换成相邻或可枚举的值。注意区分: - **自增 ID**:直接 ±1 遍历 - **雪花/时间戳 ID**:需要从其他接口或响应里收集真实样本 - **编码 ID**:base64/hex 解开看看是否是明文 ID --- ## Phase 4: 授权、支付与云开发 ### 支付与业务逻辑 小程序支付涉及商户号、订单号、签名,攻击面集中在"客户端能否影响金额或订单状态": - 提交订单时改价、改数量、改优惠券 ID,验证服务端是否重算 - 支付回调是否可伪造(回调地址、签名校验) - 订单状态是否客户端可控(如 `status` 字段) - 0 元订单、负数金额、超发优惠券 **不要进行真实支付**。用最小金额或测试商户号验证逻辑,确认问题后立即停止。 ### 云开发 使用微信云开发(CloudBase)的小程序,前端会带 `env` 环境 ID。云开发环境的权限配置错误会导致直接读写数据库: - 前端出现 `wx.cloud.init` / `cloud.database()` → 存在云开发 - 提取 `env` 后检查数据库集合的读写权限("所有用户可读"是常见误配) - 云函数若未校验调用者身份,可直接调用 ### 开放数据与第三方 小程序常接地图、OCR、短信、推送等三方 key。这些 key 硬编码在前端时: - 先判断是否属于**公开型 key**(前端设计上就要暴露的,如微信官方 key) - 只有明确是**服务端专用凭据**(AppSecret、云密钥、短信 key)才算问题,且要验证危害(能否实际调用、有无配额) - **不要把"前端存在明文配置"直接当成漏洞**。单独一个 key 字符串不构成 Finding,必须证明可利用或已泄露敏感信息。 --- ## 与其他技能的关系 - **`android-app-pentesting`**:当目标同时提供 Android 安装包、或小程序底层使用了 native 加固时,走那条技能做 APK 侧的静态/动态分析。 - **`ios-pentesting`**:iOS 客户端侧同样适用。 --- ## Finding 判定标准 提交前逐条自问: - [ ] 是否证明了**实际可利用**,而不是仅发现可疑代码? - [ ] 服务端是否确实没有复核(而不是前端拦了一下、服务端也拦了)? - [ ] 是否属于**授权范围内**的目标与数据? - [ ] 是否避免了真实资金损失与向真实用户推送测试内容? - [ ] 同一个根因是否被拆成多条 Finding 凑数? 不得作为 Finding 提交的内容: - 单纯的前端明文配置、加固存在性、版本号 - 只解包成功、只拿到接口清单,没有可证危害 - 三方公开 key(如微信官方 SDK key)的可预测性 - 无法复现、或依赖未授权范围内的数据 --- ## 常见错误 | 错误 | 后果 | 正确做法 | |------|------|----------| | 只知道 AppID 就在本地 `find` 找包 | 浪费大量时间,误判"没有攻击面" | 先向操作员索取产物,缺产物就停下来说明 | | 把解包当成终点 | 拿到源码就报告完成 | 解包只是起点,必须进 Phase 2/3 | | 信任前端的权限判断 | 漏掉最主要的越权面 | 前端所有校验一律视为不可信,实测服务端 | | 报"前端有角色字段" | 低价值、不可验证 Finding | 改值发请求,用响应差异证明越权 | | 只测只读接口 | 危害说不清楚 | 优先变更类、动钱的接口 | | 对加密包尝试破解 | 越界且无产出 | 说明需要操作员提供解包环境 |
Ver en GitHub