Skip to main content

wechat-miniprogram-pentesting

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

معلومات المصدر

المستودع
wgpsec/AboutSecurity
آخر نشاط في المصدر
١٦ أكتوبر ٢٠٢٦ في ٠٣:١٨
لغة SKILL.md المكتشفة
الصينية
النجوم
١٬٨٣٨
التفرعات
٢٥٧

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
3 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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 | 改值发请求,用响应差异证明越权 | | 只测只读接口 | 危害说不清楚 | 优先变更类、动钱的接口 | | 对加密包尝试破解 | 越界且无产出 | 说明需要操作员提供解包环境 |
عرض على GitHub