某某热点app登录sign值逆向分析
字数 946 2025-08-22 22:47:30
淘最热点APP登录sign值逆向分析教学文档
1. 环境准备
- 目标APP:淘最热点app 2.6.6
- 测试设备:Pixel 2
- 抓包工具:VPN代理(系统代理无法抓包)
2. 代理检测绕过分析
2.1 代理检测机制
APP通过System.getProperty方法检测HTTP代理设置:
System.getProperty("http.proxyHost") // 检测代理主机
System.getProperty("http.proxyPort") // 检测代理端口
2.2 绕过方法
当检测到代理设置时,APP会直接终止请求。解决方案:
- 使用VPN代理而非系统代理
- 修改APP代码绕过检测(需root或Xposed框架)
3. Sign值生成流程分析
3.1 Java层分析
sign值生成调用链:
map.put("sign", TreUtil.sign(a(map, false, false)));
关键方法a()分析
a()方法将参数按特定规则排序拼接成字符串,hook代码:
function hook_a(){
Java.perform(function(){
var MhRequestUtil = Java.use("com.maihan.tredian.net.MhRequestUtil");
MhRequestUtil.a.overload('java.util.Map', 'boolean', 'boolean').implementation = function(a1, a2, a3){
var ret = this.a(a1, a2, a3);
console.log("a=" + ret);
return ret;
}
})
}
3.2 Native层分析
sign值最终由libtre.so中的JNI函数生成,主要流程:
- 获取Java字符串的C风格表示
- 拼接固定字符串(可能为密钥)
- Base64编码处理
- SHA1哈希计算
- 转换为十六进制字符串
- 返回Java字符串
4. Native层详细逆向
4.1 关键函数定位
在libtre.so中定位以下关键函数:
sign函数:入口点j_base64_encode_new:Base64编码j_SHA1Input和j_SHA1Result:SHA1计算
4.2 Hook实现
通用Hook函数
function print_arg(addr){
try{
var module = Process.findRangeByAddress(addr);
if(module != null){
return hexdump(addr) + "\n";
}
return ptr(addr) + "\n";
} catch(e){
console.error("Error in print_arg while processing address:", addr, e);
return "Error processing address" + "\n";
}
}
function hook_native_addr(funcPtr, paramsNum){
var module = Process.findModuleByAddress(funcPtr);
Interceptor.attach(funcPtr, {
onEnter: function(args){
this.logs = [];
this.params = [];
this.logs.push("call" + module.name + "!!!!!" + ptr(funcPtr).sub(module.base) + "\n");
for(var i = 0; i < paramsNum; i++){
this.params.push(args[i]);
this.logs.push("这里是参数----->>>this.arg" + i + "进入:" + print_arg(args[i]));
}
},
onLeave: function(retval){
for(let i = 0; i < paramsNum; i++){
this.logs.push("这里是参数----->>>this.arg" + i + "返回:" + print_arg(this.params[i]));
}
this.logs.push("这里是返回值-retval 离开:" + print_arg(retval) + "\n");
console.log(this.logs);
}
})
}
Base64函数Hook
function hook_base64(){
var soAddr = Module.findBaseAddress("libtre.so");
var Base64 = soAddr.add(0x13B4 + 1);
var module = Process.findModuleByAddress(Base64);
Interceptor.attach(Base64, {
onEnter: function(args){
console.log("明文为->", args[0].readCString());
},
onLeave: function(retval){
console.log("编码后->", retval.readCString());
}
})
}
SHA1函数Hook
function hook_sha1result(){
var soAddr = Module.findBaseAddress("libtre.so");
var SHA1Result = soAddr.add(0x14C8 + 1);
hook_native_addr(SHA1Result, 2);
}
5. 加密流程验证
5.1 Base64验证
输入示例:
android_id=c7d6e3b83a3ea950&app_ver=87&channel=aliapp&code=1234&device_id=3f4cd28edd6f18f9b5e7abf46c806f35&device_name=google Pixel 2&device_udid=aa8665f814b51ac0231cc7960a586c0d&from=app&getui_push_id=722ec4b874f67b5d1f96de6e757da7d4&imei1=&imei2=&mac=9A:E2:8A:ED:F5:A3&nonce=67wqsl1732873801016&os_ver_code=29&phone=11111111111&system=1×tamp=1732873801
输出可通过在线Base64工具验证。
5.2 SHA1验证
使用标准SHA1算法对Base64结果进行哈希计算,与APP输出对比验证。
6. 完整Sign生成算法
- 将所有请求参数按字母顺序排序
- 拼接成key=value&形式的字符串
- 拼接固定密钥(需逆向确定)
- 进行Base64编码
- 对结果进行SHA1哈希
- 将哈希结果转换为十六进制字符串
7. 实现示例(Python)
import base64
import hashlib
def generate_sign(params, secret_key):
# 1. 参数排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接字符串
param_str = '&'.join([f"{k}={v}" for k, v in sorted_params])
# 3. 拼接密钥
combined = param_str + secret_key
# 4. Base64编码
b64_encoded = base64.b64encode(combined.encode()).decode()
# 5. SHA1哈希
sha1 = hashlib.sha1(b64_encoded.encode())
# 6. 十六进制表示
return sha1.hexdigest()
8. 总结
淘最热点APP的sign值生成流程采用了典型的参数排序+密钥+Base64+SHA1的方案,这种设计:
- 保证了请求参数的完整性
- 通过密钥防止篡改
- 使用标准加密算法确保安全性
逆向过程中需要注意:
- 代理检测的绕过
- JNI函数的正确识别
- 加密流程的完整验证