记一次实战登陆口Js逆向分析
字数 1513 2025-08-20 18:17:07
实战登陆口Js逆向分析教学文档
0x00 前言
本文详细讲解如何对登陆接口进行Js逆向分析,涉及AES+SM3加密算法的逆向过程。通过本教程,您将学习到:
- 如何定位前端加密逻辑
- 如何设置断点进行调试
- 如何分析加密函数调用链
- 如何逆向AES和SM3算法实现
0x01 踩点阶段
1. 基础登陆页面分析
首先访问目标网站,观察以下特征:
- 所有未授权访问都会被重定向到/login界面
- 检查页面源代码中的JavaScript文件
2. JS文件分析技巧
在JS文件中寻找以下关键信息:
- 硬编码的用户名或密码
- 加密函数定义(AES、SM3、RSA等)
- 接口调用逻辑
- 参数生成方式
发现:在JS文件中找到了用户名列表,这可以作为爆破的起点
3. 抓包分析
使用Burp Suite或浏览器开发者工具抓取登录请求,观察:
- 请求参数是否加密
- 是否有签名参数(如sign)
- 请求头特殊字段
示例请求特征:
POST /login
{
"postdata": "加密数据",
"sign": "xxxxxx",
"ywid": "api.base.check.xxxxxx"
}
0x02 断点设置技巧
1. XHR请求断点
适用场景:当参数被混淆或难以直接定位时
设置方法:
- 在Chrome开发者工具中打开Sources面板
- 在右侧XHR Breakpoints中添加断点条件
- 例如对接口路径包含"ApiServlet"的请求设置断点
优点:不需要预先知道加密参数
缺点:需要跟踪调用堆栈
2. 关键词断点
常用关键词:
- AES/Des/RSA/SM3
- encrypt/decrypt
- sign/signature
- 接口唯一标识(如ywid参数值)
设置方法:
- 在Sources面板中全局搜索关键词
- 找到相关函数后直接设置断点
0x03 加密逻辑分析
1. 定位加密函数
通过断点调试发现:
- 用户名和密码都经过函数
o处理 - 数据以JSON格式传输
- postdata中包含加密后的用户名和密码
2. 函数调用链分析
步骤:
- 进入函数
o的断点 - 使用Step Into逐步跟踪
- 观察参数变化和返回值
- 记录加密过程中的关键操作
发现:
- 用户名
sjry和密码gt3mm都经过多层加密 - 最终组合成postdata发送
0x04 AES+SM3算法逆向
1. AES加密分析
定位方法:
- 搜索"CryptoJS.AES"
- 查找encrypt/decrypt调用
- 跟踪密钥生成逻辑
关键参数:
- 密钥(可能硬编码或动态生成)
- 加密模式(CBC/ECB等)
- 填充方式(PKCS7等)
- IV向量(如果有)
2. SM3哈希算法分析
特征:
- 国密算法
- 输出长度为256位
- 常用于生成签名
定位方法:
- 搜索"SM3"或"国密"
- 查找摘要生成逻辑
- 通常用于sign参数生成
3. 加密流程还原
通过分析得出典型加密流程:
- 用户名/密码分别AES加密
- 组合加密结果生成中间字符串
- 使用SM3生成签名
- 构造最终POST数据
0x05 实战复现
1. 提取加密函数
从JS中找到核心加密函数,例如:
function o(data) {
var key = CryptoJS.enc.Utf8.parse("硬编码密钥");
var iv = CryptoJS.enc.Utf8.parse("硬编码IV");
var encrypted = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
2. 构造Python等价实现
使用pycryptodome实现相同逻辑:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import binascii
def aes_encrypt(data):
key = b'硬编码密钥'.ljust(16, b'\0')[:16] # 确保16字节
iv = b'硬编码IV'.ljust(16, b'\0')[:16]
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_data = pad(data.encode(), AES.block_size)
encrypted = cipher.encrypt(padded_data)
return binascii.hexlify(encrypted).decode()
3. SM3签名实现
使用gmssl库实现SM3:
from gmssl import sm3
def sm3_hash(data):
sm3_crypt = sm3.sm3()
sm3_crypt.update(data.encode())
return sm3_crypt.hexdigest()
0x06 自动化脚本
1. 完整登录流程实现
import requests
import json
def login(username, password):
# 1. AES加密用户名和密码
enc_username = aes_encrypt(username)
enc_password = aes_encrypt(password)
# 2. 构造请求数据
postdata = {
"user": enc_username,
"pass": enc_password
}
json_data = json.dumps(postdata)
# 3. 生成SM3签名
sign = sm3_hash(json_data + "固定盐值")
# 4. 发送请求
headers = {
"Content-Type": "application/json",
"X-Sign": sign
}
response = requests.post("https://target.com/login",
data=json_data,
headers=headers)
return response.json()
0x07 防御建议
为防止此类逆向分析,建议:
- 避免在前端硬编码密钥
- 使用动态密钥或密钥派生函数
- 增加代码混淆
- 使用WebAssembly实现核心加密
- 添加时间戳和一次性随机数防御重放攻击
0x08 总结
本教程详细讲解了:
- 从JS文件中寻找加密线索的方法
- 断点调试技巧
- AES和SM3算法的逆向分析
- Python实现等价加密逻辑
- 完整自动化登录脚本编写
通过系统性的分析,即使面对复杂的加密逻辑也能逐步破解,最终实现自动化登录。