京东h5st4.7逆向分析
字数 1401 2025-08-19 12:42:02
京东h5st 4.7参数逆向分析教学文档
一、前言
京东h5st参数是京东网站重要的反爬机制,目前已经升级到4.7版本并逐渐VMP化。本文档将详细分析h5st 4.7参数的生成过程,包括定位方法、逆向分析流程和关键加密函数解析。
二、逆向目标
- 目标参数:京东h5st 4.7
- 目标网站:aHR0cHM6Ly93d3cuamQuY29tLw==(京东官网)
- 相关参数:h5st、x-api-eid-token(风控参数)
三、流程分析
1. 抓包分析
通过抓包可观察到:
- h5st参数版本号为4.7
- x-api-eid-token由接口返回,由大量浏览器环境和指纹信息生成(可先写死)
2. h5st参数定位
定位方法:
- 搜索大法或堆栈追踪快速定位生成位置
- 关键调用链:
colorParamSign→window.PSign.sign异步函数
四、逆向分析
1. 参数生成入口
h5st参数生成位于VMP文件中,主要特征:
- 加密流程和函数大部分VMP化
- 保留了一些特征点(CryptoJS, AES, SHA, Base64等)
2. 分析方法
方法一:在所有vmp操作的call位置打日志断点(不推荐,日志点过多)
方法二:在关键加密函数位置断点分析(推荐):
- 搜索常见加密函数特征
- 找到约10处加密/编码操作函数
- 这些函数格式统一,采用ob模式混淆
3. 加密函数结构
加密函数导出结构:
传入一个对象接收导出的加密函数
初始将o函数的返回值赋值给HS对象
后续传入HS对象到o函数再进行导出
HS对象包含所有加密函数,可通过以下方式获取:
- 在拼接生成h5st的位置断点
- 输出HS对象
- 在关键加密函数(AES、哈希、Base64)处下断点
4. 关键加密流程
AES加密
- 参数:n, a(可能是key和iv)
- 测试发现与标准AES结果不一致(存在魔改)
- 示例代码:
const CryptoJS = require('crypto-js');
var Bytes = {
words: [1598895705, 1063548518, 1312043094, 1296456536],
sigBytes: 16
};
var key = CryptoJS.enc.Utf8.stringify(Bytes);
console.log(key);
var Bytes = CryptoJS.enc.Utf8.parse(key);
console.log(Bytes);
Base64编码
- 对AES加密结果进行编码
- 也是魔改版本
加密数据来源
test参数来自request_algo接口返回rd和加密函数都是动态的
expandParams
- 使用魔改AES加密生成
- key值不同
- 明文主要是环境值(可先固定)
5. SHA256加密
加密明文结构:
test函数生成的加密结果 +
colorParamSign的拼接 +
test函数生成的加密结果
示例明文:
'5571a8dda12c510ad1922b90d6b048aba648d9a8c2fc679927fc1e7102520489appid:search-pc-java&body:64ef977e15f853295527f3ce1f15fc980963c43f27c40066d26dd19b542d0bd4&client:pc&clientVersion:1.0.0&functionId:pc_search_s_new&t:17152462710115571a8dda12c510ad1922b90d6b048aba648d9a8c2fc679927fc1e7102520489'
加密结果示例:
626bad7f7ebe126bb799ac619409778c8808864ad364bcb3d6a42bfb14af47b7
6. h5st参数拼接
最终h5st参数由以下部分组成:
e:SHA256加密结果t:时间戳r:由时间戳转换生成n:第一次AES加密+魔改Base64编码结果_fingerprint:可先写死(算法生成)_appid:可先写死(页面获取)_token:来自request_algo接口返回
时间戳转换函数:
function format() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : Date.now(),
t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "yyyy-MM-dd",
r = new Date(e),
n = t,
a = {
"M+": r.getMonth() + 1,
"d+": r.getDate(),
"D+": r.getDate(),
"h+": r.getHours(),
"H+": r.getHours(),
"m+": r.getMinutes(),
"s+": r.getSeconds(),
"w+": r.getDay(),
"q+": Math.floor((r.getMonth() + 3) / 3),
"S+": r.getMilliseconds()
};
return /(y+)/i.test(n) && (n = n.replace(RegExp.$1, "".concat(r.getFullYear()).substr(4 - RegExp.$1.length))),
w_(a).forEach((function(e) {
if (new RegExp("(".concat(e, ")")).test(n)) {
var t, r = "S+" === e ? "000" : "00";
n = n.replace(RegExp.$1, 1 == RegExp.$1.length ? a[e] : j_(t = "".concat(r)).call(t, a[e]).substr("".concat(a[e]).length))
}
})), n
};
console.log(format(1715246309293, "yyyyMMddhhmmssSSS")) // 输出:20240509171829293
五、HS对象处理
虽然代码有ob混淆,但可以直接手动扣取:
- 约10处结构相似的函数
- 混淆部分不多,无需完全还原
- 扣取完成后输出HS对象即可直接调用加密函数
注意:必须校验与浏览器加密结果一致
六、结果验证
正确生成的h5st参数:
- 不会出现
<Response [403]>的情况 - 100%可以获取到数据
七、总结
- h5st 4.7参数生成流程复杂但可追踪
- 关键点在于HS对象中加密函数的获取
- 虽然部分加密被魔改,但通过断点分析可还原
- 时间戳转换和参数拼接是最后关键步骤
- 验证时需确保各环节结果与浏览器一致
八、注意事项
- 本文仅供学习交流使用
- 严禁用于商业用途和非法用途
- 不提供完整代码实现
- 所有敏感信息均已做脱敏处理
- 京东可能随时更新参数生成方式,需持续跟踪