js逆向实战练习一:sign签名破解
字数 1365 2025-08-23 18:31:25
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 环境准备
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. 验证签名
- 确保Python脚本中的
ver、mt值与实际请求一致 - 将生成的sign值填入请求参数
- 发送请求验证是否成功
6. 关键技巧总结
- 断点设置:在疑似签名生成处设置断点
- 调用堆栈:通过调用堆栈逆向追踪签名函数
- 单步调试:使用"单步进入"和"跳过"功能逐步分析
- 函数搜索:使用
function(和function =两种模式搜索函数定义 - 依赖分析:逐层分析函数依赖关系,确保提取完整
- 参数验证:多次调试确认所有参与签名的参数
7. 常见问题解决
- 函数未定义错误:检查是否提取了所有依赖函数
- 签名不匹配:确保所有参数值与实际请求一致
- 编码问题:确保JS文件保存为UTF-8格式
- 环境差异:注意Node.js与浏览器环境的差异
8. 防御措施分析
该签名机制存在以下安全弱点:
- 签名算法暴露在前端JS中
- 没有使用动态密钥
- 没有加入随机干扰因子
- 签名参数顺序固定
更安全的签名方案应考虑:
- 使用后端生成签名
- 加入时效性验证
- 使用动态密钥
- 加入随机干扰因子
9. 完整流程总结
- 分析请求参数,确定签名参数
- 使用开发者工具定位签名生成代码
- 通过断点和单步调试确认签名函数
- 提取所有依赖的JS函数
- 重构签名生成代码
- 使用Python调用验证
- 应用于实际请求
通过这个案例,可以掌握基本的JS逆向和签名破解技术,适用于大多数前端生成的签名场景。