记一次微信小程序逆向
字数 1414 2025-08-19 12:42:10

微信小程序逆向分析与安全测试实战教程

一、前言

本教程详细记录了一次微信小程序逆向分析与安全测试的全过程,涵盖反编译、加密分析、签名破解、重放攻击等技术要点。通过本案例,读者可以学习到微信小程序安全测试的完整方法论。

二、工具准备

  1. 反编译工具

    • wxapkg解密工具:https://github.com/wux1an/wxapkg
    • 用于解包微信小程序的.wxapkg文件
  2. 加密分析工具

    • 在线AES工具:https://www.wushuangzl.com/tools/aes/
    • 用于验证加密算法
  3. 抓包工具

    • Burp Suite + autoDecoder插件
    • 用于拦截和自动加解密流量
  4. 开发环境

    • Python 3.x
    • PyCryptodome库(AES加解密)
    • hashlib库(MD5计算)

三、反编译小程序

  1. 获取小程序.wxapkg文件:

    • 从微信缓存目录中提取目标小程序的包文件
  2. 使用wxapkg工具反编译:

    wxapkg -d input.wxapkg output_dir
    
    • 反编译后得到JS源码,便于后续分析

四、加密分析

1. 识别加密方式

通过抓包和源码分析,确认小程序使用:

  • AES-CBC模式加密
  • 固定密钥:Wet2C8d34f62ndi3
  • 固定IV:K6iv85jBD8jgf32D

2. 加解密实现

Python实现AES加解密:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

def aes_encrypt(data, key, iv):
    key_bytes = key.encode('utf-8')
    iv_bytes = iv.encode('utf-8')
    cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
    ct_bytes = cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))
    return base64.b64encode(ct_bytes).decode('utf-8')

def aes_decrypt(encrypted_data, key, iv):
    key_bytes = key.encode('utf-8')
    iv_bytes = iv.encode('utf-8')
    cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
    pt_bytes = cipher.decrypt(base64.b64decode(encrypted_data))
    return unpad(pt_bytes, AES.block_size).decode('utf-8')

五、签名机制分析

1. Sign签名生成规则

通过分析JS源码,发现签名生成流程:

  1. 对所有参数按键名排序
  2. 拼接键名和键值(如key1value1key2value2...
  3. 末尾添加固定密钥rDJiNB9j7vD2
  4. 计算MD5哈希值

Python实现:

import hashlib

def generate_sign(data, secret_key):
    sorted_data = sorted(data.items())
    joined_data = ''.join([f'{key}{value}' for key, value in sorted_data])
    joined_data_with_key = joined_data + secret_key
    return hashlib.md5(joined_data_with_key.encode()).hexdigest()

2. 时间戳与随机数

  • timestamp:当前UNIX时间戳
  • nonce:由时间戳后3位+3位随机数组成
    • 如果时间戳后3位以0开头,则去掉前导0

Python实现:

import time
import random

def generate_nonce():
    timestamp = int(time.time())
    last_three = str(timestamp)[-3:]
    if last_three[0] == '0':
        last_three = last_three[1:]
    random_part = ''.join(str(random.randint(0,9)) for _ in range(6-len(last_three)))
    return int(last_three + random_part)

六、Burp Suite自动化配置

  1. 安装autoDecoder插件
  2. 配置请求/响应加解密规则:
    • 请求解密正则:匹配加密请求体
    • 响应解密正则:匹配加密响应体
  3. 配置加解密函数(使用上述Python实现)

七、接口安全测试

1. 越权测试

  • 测试uid参数是否可篡改
  • 发现uidtoken绑定,无法直接越权

2. 敏感接口发现

通过分析JS源码发现多个潜在敏感接口:

  • /v3/api.php/TeacherCourse/getStudentList
  • /v3/api.php/Exam/classStudentList

3. 数据泄露漏洞

  • 普通用户身份可访问教师权限接口
  • 通过修改course_id参数可遍历获取学生信息
  • 泄露数据包含:学号、姓名、学院、专业等

八、防御建议

  1. 加密增强

    • 避免使用固定密钥和IV
    • 考虑使用动态密钥或非对称加密
  2. 签名机制改进

    • 增加签名时效性验证
    • 使用更复杂的签名算法(如HMAC-SHA256)
  3. 接口安全

    • 严格权限控制
    • 敏感接口增加二次验证
    • 对批量查询接口实施速率限制
  4. 混淆加固

    • 对关键JS代码进行混淆
    • 使用小程序加固方案

九、完整测试脚本

import hashlib
import time
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import json

# AES配置
AES_KEY = "Wet2C8d34f62ndi3"
AES_IV = "K6iv85jBD8jgf32D"

# 签名密钥
SIGN_KEY = "rDJiNB9j7vD2"

def aes_encrypt(data, key=AES_KEY, iv=AES_IV):
    key_bytes = key.encode('utf-8')
    iv_bytes = iv.encode('utf-8')
    cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
    ct_bytes = cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))
    return base64.b64encode(ct_bytes).decode('utf-8')

def aes_decrypt(encrypted_data, key=AES_KEY, iv=AES_IV):
    key_bytes = key.encode('utf-8')
    iv_bytes = iv.encode('utf-8')
    cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
    pt_bytes = cipher.decrypt(base64.b64decode(encrypted_data))
    return unpad(pt_bytes, AES.block_size).decode('utf-8')

def generate_sign(data, secret_key=SIGN_KEY):
    sorted_data = sorted(data.items())
    joined_data = ''.join([f'{key}{value}' for key, value in sorted_data])
    joined_data_with_key = joined_data + secret_key
    return hashlib.md5(joined_data_with_key.encode()).hexdigest()

def generate_nonce():
    timestamp = int(time.time())
    last_three = str(timestamp)[-3:]
    if last_three[0] == '0':
        last_three = last_three[1:]
    random_part = ''.join(str(random.randint(0,9)) for _ in range(6-len(last_three)))
    return int(last_three + random_part)

def build_request_payload(base_data):
    timestamp = int(time.time())
    nonce = generate_nonce()
    data = {
        **base_data,
        "timestamp": timestamp,
        "nonce": nonce
    }
    data["sign"] = generate_sign(data)
    return aes_encrypt(json.dumps(data))

# 示例使用
if __name__ == "__main__":
    base_data = {
        "uid": 100123,
        "token": "216A3906F97C26A29EC0FE10F3956692",
        "school_id": 464,
        "course_id": 0,
        "student_num": "123"
    }
    
    encrypted = build_request_payload(base_data)
    print("Encrypted:", encrypted)
    
    # 解密测试
    decrypted = aes_decrypt(encrypted)
    print("Decrypted:", decrypted)

十、总结

本案例展示了微信小程序安全测试的完整流程,从反编译到加密分析,再到接口安全测试。关键点包括:

  1. 小程序包反编译技术
  2. AES加密算法的识别与破解
  3. 签名机制的逆向分析
  4. Burp Suite自动化测试配置
  5. 接口权限绕过测试方法

通过这种系统化的分析方法,可以有效发现小程序中存在的各类安全问题。

微信小程序逆向分析与安全测试实战教程 一、前言 本教程详细记录了一次微信小程序逆向分析与安全测试的全过程,涵盖反编译、加密分析、签名破解、重放攻击等技术要点。通过本案例,读者可以学习到微信小程序安全测试的完整方法论。 二、工具准备 反编译工具 : wxapkg解密工具:https://github.com/wux1an/wxapkg 用于解包微信小程序的.wxapkg文件 加密分析工具 : 在线AES工具:https://www.wushuangzl.com/tools/aes/ 用于验证加密算法 抓包工具 : Burp Suite + autoDecoder插件 用于拦截和自动加解密流量 开发环境 : Python 3.x PyCryptodome库(AES加解密) hashlib库(MD5计算) 三、反编译小程序 获取小程序.wxapkg文件: 从微信缓存目录中提取目标小程序的包文件 使用wxapkg工具反编译: 反编译后得到JS源码,便于后续分析 四、加密分析 1. 识别加密方式 通过抓包和源码分析,确认小程序使用: AES-CBC 模式加密 固定密钥: Wet2C8d34f62ndi3 固定IV: K6iv85jBD8jgf32D 2. 加解密实现 Python实现AES加解密: 五、签名机制分析 1. Sign签名生成规则 通过分析JS源码,发现签名生成流程: 对所有参数按键名排序 拼接键名和键值(如 key1value1key2value2... ) 末尾添加固定密钥 rDJiNB9j7vD2 计算MD5哈希值 Python实现: 2. 时间戳与随机数 timestamp :当前UNIX时间戳 nonce :由时间戳后3位+3位随机数组成 如果时间戳后3位以0开头,则去掉前导0 Python实现: 六、Burp Suite自动化配置 安装autoDecoder插件 配置请求/响应加解密规则: 请求解密正则:匹配加密请求体 响应解密正则:匹配加密响应体 配置加解密函数(使用上述Python实现) 七、接口安全测试 1. 越权测试 测试 uid 参数是否可篡改 发现 uid 与 token 绑定,无法直接越权 2. 敏感接口发现 通过分析JS源码发现多个潜在敏感接口: /v3/api.php/TeacherCourse/getStudentList /v3/api.php/Exam/classStudentList 3. 数据泄露漏洞 普通用户身份可访问教师权限接口 通过修改 course_id 参数可遍历获取学生信息 泄露数据包含:学号、姓名、学院、专业等 八、防御建议 加密增强 : 避免使用固定密钥和IV 考虑使用动态密钥或非对称加密 签名机制改进 : 增加签名时效性验证 使用更复杂的签名算法(如HMAC-SHA256) 接口安全 : 严格权限控制 敏感接口增加二次验证 对批量查询接口实施速率限制 混淆加固 : 对关键JS代码进行混淆 使用小程序加固方案 九、完整测试脚本 十、总结 本案例展示了微信小程序安全测试的完整流程,从反编译到加密分析,再到接口安全测试。关键点包括: 小程序包反编译技术 AES加密算法的识别与破解 签名机制的逆向分析 Burp Suite自动化测试配置 接口权限绕过测试方法 通过这种系统化的分析方法,可以有效发现小程序中存在的各类安全问题。