js逆向实战练习一:sign签名破解
字数 1365 2025-08-23 18:31:25

JS逆向实战:Sign签名破解教学文档

1. 案例背景

本案例研究的是一个网站API接口/api/member/getMobile,该接口需要以下参数:

  • ver:版本号
  • mt:时间戳
  • username:用户名
  • sign:签名值

当改变vermtusername中的任意一个值时,服务器会返回签名错误,说明sign是由这三个参数共同生成的。

2. 逆向分析步骤

2.1 寻找签名生成位置

方法一:XHR断点

  1. 在开发者工具中添加XHR断点
  2. 触发API请求
  3. 发现断点触发时sign已生成,此方法无效

方法二:调用堆栈分析

  1. 找到请求数据包
  2. 查看调用堆栈(Call Stack)
  3. 发现可疑的"LoginForm"项
  4. 查看对应JS文件,找到疑似签名生成代码

2.2 定位签名函数

  1. 在疑似签名代码处(如sign: M({)添加断点
  2. 触发请求,程序在断点处暂停
  3. 使用"单步调试"跟进
  4. 发现跳转到function g5(e),e值为用户名
  5. 继续调试发现经过IQ(o)函数后生成类似sign的值
  6. 确认IQ(o)是签名生成的关键函数

2.3 参数追踪

  1. 发现第一次调用g5(e)时只有用户名
  2. 继续调试发现第二次调用g5(e)时包含用户名、mt和ver
  3. 确认g5函数是签名生成函数

3. 代码提取与重构

3.1 提取关键函数

  1. 首先提取g5函数
  2. 发现g5依赖IQ()函数
  3. 在JS文件中搜索IQ(IQ =找到IQ函数定义
  4. 提取IQ函数后发现其依赖TQ函数
  5. 同样方法搜索并提取TQ函数

3.2 构建完整签名生成代码

最终需要提取以下函数:

  1. g5 - 主签名函数
  2. IQ - 签名处理函数
  3. TQ - 辅助加密函数

4. Python调用JS代码

4.1 环境准备

import execjs

# 读取JS文件
with open('sign.js', 'r', encoding='utf-8') as f:
    js_code = f.read()

4.2 调用签名函数

# 创建JS执行环境
ctx = execjs.compile(js_code)

# 准备参数
params = {
    "ver": "1.0",
    "mt": "时间戳",
    "username": "目标用户名"
}

# 调用签名函数
sign = ctx.call('g5', params)

print(f"生成的签名: {sign}")

5. 验证签名

  1. 确保Python脚本中的vermt值与实际请求一致
  2. 将生成的sign值填入请求参数
  3. 发送请求验证是否成功

6. 关键技巧总结

  1. 断点设置:在疑似签名生成处设置断点
  2. 调用堆栈:通过调用堆栈逆向追踪签名函数
  3. 单步调试:使用"单步进入"和"跳过"功能逐步分析
  4. 函数搜索:使用function(function =两种模式搜索函数定义
  5. 依赖分析:逐层分析函数依赖关系,确保提取完整
  6. 参数验证:多次调试确认所有参与签名的参数

7. 常见问题解决

  1. 函数未定义错误:检查是否提取了所有依赖函数
  2. 签名不匹配:确保所有参数值与实际请求一致
  3. 编码问题:确保JS文件保存为UTF-8格式
  4. 环境差异:注意Node.js与浏览器环境的差异

8. 防御措施分析

该签名机制存在以下安全弱点:

  1. 签名算法暴露在前端JS中
  2. 没有使用动态密钥
  3. 没有加入随机干扰因子
  4. 签名参数顺序固定

更安全的签名方案应考虑:

  1. 使用后端生成签名
  2. 加入时效性验证
  3. 使用动态密钥
  4. 加入随机干扰因子

9. 完整流程总结

  1. 分析请求参数,确定签名参数
  2. 使用开发者工具定位签名生成代码
  3. 通过断点和单步调试确认签名函数
  4. 提取所有依赖的JS函数
  5. 重构签名生成代码
  6. 使用Python调用验证
  7. 应用于实际请求

通过这个案例,可以掌握基本的JS逆向和签名破解技术,适用于大多数前端生成的签名场景。

JS逆向实战:Sign签名破解教学文档 1. 案例背景 本案例研究的是一个网站API接口 /api/member/getMobile ,该接口需要以下参数: ver :版本号 mt :时间戳 username :用户名 sign :签名值 当改变 ver 、 mt 、 username 中的任意一个值时,服务器会返回签名错误,说明 sign 是由这三个参数共同生成的。 2. 逆向分析步骤 2.1 寻找签名生成位置 方法一:XHR断点 在开发者工具中添加XHR断点 触发API请求 发现断点触发时sign已生成,此方法无效 方法二:调用堆栈分析 找到请求数据包 查看调用堆栈(Call Stack) 发现可疑的"LoginForm"项 查看对应JS文件,找到疑似签名生成代码 2.2 定位签名函数 在疑似签名代码处(如 sign: M({ )添加断点 触发请求,程序在断点处暂停 使用"单步调试"跟进 发现跳转到 function g5(e) ,e值为用户名 继续调试发现经过 IQ(o) 函数后生成类似sign的值 确认 IQ(o) 是签名生成的关键函数 2.3 参数追踪 发现第一次调用 g5(e) 时只有用户名 继续调试发现第二次调用 g5(e) 时包含用户名、mt和ver 确认 g5 函数是签名生成函数 3. 代码提取与重构 3.1 提取关键函数 首先提取 g5 函数 发现 g5 依赖 IQ() 函数 在JS文件中搜索 IQ( 或 IQ = 找到 IQ 函数定义 提取 IQ 函数后发现其依赖 TQ 函数 同样方法搜索并提取 TQ 函数 3.2 构建完整签名生成代码 最终需要提取以下函数: g5 - 主签名函数 IQ - 签名处理函数 TQ - 辅助加密函数 4. Python调用JS代码 4.1 环境准备 4.2 调用签名函数 5. 验证签名 确保Python脚本中的 ver 、 mt 值与实际请求一致 将生成的sign值填入请求参数 发送请求验证是否成功 6. 关键技巧总结 断点设置 :在疑似签名生成处设置断点 调用堆栈 :通过调用堆栈逆向追踪签名函数 单步调试 :使用"单步进入"和"跳过"功能逐步分析 函数搜索 :使用 function( 和 function = 两种模式搜索函数定义 依赖分析 :逐层分析函数依赖关系,确保提取完整 参数验证 :多次调试确认所有参与签名的参数 7. 常见问题解决 函数未定义错误 :检查是否提取了所有依赖函数 签名不匹配 :确保所有参数值与实际请求一致 编码问题 :确保JS文件保存为UTF-8格式 环境差异 :注意Node.js与浏览器环境的差异 8. 防御措施分析 该签名机制存在以下安全弱点: 签名算法暴露在前端JS中 没有使用动态密钥 没有加入随机干扰因子 签名参数顺序固定 更安全的签名方案应考虑: 使用后端生成签名 加入时效性验证 使用动态密钥 加入随机干扰因子 9. 完整流程总结 分析请求参数,确定签名参数 使用开发者工具定位签名生成代码 通过断点和单步调试确认签名函数 提取所有依赖的JS函数 重构签名生成代码 使用Python调用验证 应用于实际请求 通过这个案例,可以掌握基本的JS逆向和签名破解技术,适用于大多数前端生成的签名场景。