免责声明
文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业和非法用途,否则由此产生的一切后果与作者无关。若有侵权,请在公众号【爬虫逆向小林哥】联系作者
01
—
逆向目标
今天是某东合集的第二弹: h5st 4.1版本,分析的接口是m端的我的关注:
https://wqs.jd.com/my/fav/goods_fav.shtml?sceneval=2&jxsid=16999285695679990439&appCode=ms0ca95114&ptag=7155.1.8
02
—
抓包分析
functionId=queryFollowProduct
在前一篇文章已经分析过了x-api-eid-token,本文主要是这个h5st
03
—
逆向过程
搜索
先是把e.body进行sha256然后K[e].sign加密,最后回调拿到结果,先来看sha256
sha256_digest
参数就是我们上面抓包参数有个body参数
本地用个库结果一样没啥好讲的了
接着看K[e].sign
K[e].sign
进入sign
下面就是漫长的异步跟栈,进入e
到t
加密的逻辑就在这个平坦流里面了,异步跟栈要是不太熟的话记得翻翻之前的文章。
在几个return出打上断点
case4
生成this中的token、fingerprint等
case6
对版本参数和环境加密
this[n(397, 0, 386)]();
进入这个函数,接下来又是异步跟栈
然后就是到这里
下面分别对应加密data、iv、key 典型的aes-cbc
env = {
"sua": "Windows NT 10.0; Win64; x64",
"pp": {
"p2": ""
},
"extend": {
"pm": 0,
"wd": 0,
"l": 0,
"ls": 5,
"wk": 0
},
"random": "j52LDo5u-C",
"referer": "",
"v": "v1.6.1",
"fp": "ni6mz59tt9ggt5w9"
};
function collect() {
let iv = CryptoJS.enc.Utf8.parse('0102030405060708'), // 偏移量
key = CryptoJS.enc.Utf8.parse('HL4|FW#Chc3#q?0)'), // key
data = CryptoJS.enc.Utf8.parse(JSON.stringify(env, null, 2)); // data
aes = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return aes.ciphertext.toString()//aes.toString()
}
到这里版本环境加密就分析完了,接下来看重点
case8
s = this[n(328, 0, 418)](u, c),
u就是 需要传入的对象只要有appid、body、functionId,c就是我们上面aes加密的值
进入加密函数,然后发现又是平坦流
在case1打上断点,这边有几个我们要分析的参数
var c = this[o(0, 1146, 0, 1282)]
, s = this[r(-194, 0, 0, -58) + "ken"]
, l = this[r(30, 0, 0, 134) + "nt"]
, f = this[r(45, 0, 0, 27)];
就是去拿appid、token等
回头发现case0忘记分析了,就是把时间戳格式化
function jd() {
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
, i = {
"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))),
Object.keys(i).forEach(function (e) {
if (new RegExp("(".concat(e, ")")).test(n)) {
var t = "S+" === e ? "000" : "00";
n = n.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : "".concat(t).concat(i[e]).substr("".concat(i[e]).length))
}
}),
n
}
注意case2给格式化好的时间后面加了盐04
case3
对上面的参数进行sha512
注意拼接和加盐(版本改变这里经常会变)
然后接着往下看,简单做的逆向回推:
k.h5st = b,
var b = this[......](w, A, u, n);
w = this[r(-79, 0, 0, -125)](p, t);
看w
主要就是上面的 512结果跟传入参数进行拼接然后md5
最后b就是把生成的几个参数拼接
具体实现:
let x = [""['concat'](l), ""['concat'](fingerprint), ""['concat'](_appId), ""['concat'](_token), "".concat(A), ""['concat'](_version), ""['concat'](s), ""['concat'](r)].join(";");
04
—
效果
接口不是强校验,但是不加这个参数并发跑几次就会出现返回为空,加上了就不会有问题
05
—
算法还原
90行纯算
06
—
归纳总结
添加好友回复:交流群
原文始发于微信公众号(爬虫逆向小林哥):【逆向案例】某东合集m端h5st 4.1(二)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论