h5st最新5.1版本逆向分析
申明
本文仅用来记录学习过程以免日后忘了,如有侵权请联系删除。
定位h5st生成的位置
通过关键字“sign”搜索,可以定位到window.PSign.sign(f)这个位置,f参数的值为{ "appid": "pc-item-soa", "functionId": "pc_detailpage_wareBusiness", "client": "pc", "clientVersion": "1.0.0", "t": 1749631063675, "body": "bbc844*****c5c9cae4356" },这里的body是把请求params里面的body经过标准的sha256加密得到的

打上断点动态调试一下,会定位到 c = new window.ParamsSignMain和 c.sign® ,

单步跟进c.sign®,会定位到 this._KaTeX parse error: Expected group after '_' at position 7: sdnmd(_̲CW),通过观看入参和返回值,可以确定这里就是真正调用h5st加密方法的位置。

动态插桩,事半功倍
this._KaTeX parse error: Expected group after '_' at position 7: sdnmd(_̲CW)方法这里打上日志断点,"h5st:",_$Cz['h5st']

接着搜索MD5,找到md5算法的_doFinalize方法并插入日志断点"md5加密结果:", _$CN.toString()

搜索Base64,找到base64的encode方法,这里是一个循环,直接找到循环return的位置打上日志断点"base64加密结果:",p[0]

如法炮制,找到sha256的_doFinalize方法,打上日志断点"sha256 加密结果:", this._hash.toString()

接下来搜索关键字“_createHelper”,这几个加密方法都会通过_createHelper方法进行调用,插入日志断点"加密参数:",_$CV

最后找到下图所示方法,这是h5st开头那个日期生成的地方,插入日志断点"传入时间戳:",_$CW,"返回时间:",_$Cv

打好以上日志断点后,就可以通过日志分析还原出h5st算法
日志分析,十分钟还原算法逻辑
执行一次代码,观察一下日志,日志信息非常简洁,逻辑也非常清晰,

body = params['body']
sha256_hash = hashlib.sha256()
# 更新数据(需要传入字节流)
sha256_hash.update(body.encode('utf-8'))
# 获取十六进制的哈希值
sha256_body = sha256_hash.hexdigest()
t = int(time.time()*1000)
dt = format_time(t)
msg = f'{token}{fingerprint}{dt}40{appId}{salt}'
print("加密参数: "+msg)
if func_name == 'HmacSHA256':
h1 = algo_encrypt({'data':msg,'func_name':'hmacsha256'})['result']
elif func_name == 'SHA256':
h1 = algo_encrypt({'data':msg,'func_name':'sha256'})['result']
elif func_name == 'MD5':
h1 = algo_encrypt({'data':msg,'func_name':'md5'})['result']
elif func_name == 'HmacMD5':
h1 = algo_encrypt({'data':msg,'func_name':'hmacmd5'})['result']
else:
logger.error("未知的加密方法")
return None
first_encrypt = h1
# 第二步:body加密
print("md5加密结果: "+first_encrypt)
msg2 = f"{first_encrypt}appid:{params['appid']}&body:{sha256_body}&client:{params['client']}&clientVersion:{params['clientVersion']}&functionId:{params['functionId']}&t:{params['t']}{first_encrypt}"
print("加密参数: "+msg2)
result2 = algo_encrypt({'data':msg2,'func_name':'sha256'})['result']
print("sha256 加密结果: "+result2)
msg3 = f"{first_encrypt}appid:{params['appid']}&functionId:{params['functionId']}{first_encrypt}"
print("加密参数: " + msg3)
a = algo_encrypt({'data':msg3,'func_name':'sha256'})['result']
print("sha256 加密结果: " + a)
tenth_str = 'appid,body,client,clientVersion,functionId,t'
tenth_encrypt = algo_encrypt({'data':tenth_str,'func_name':'base64'})['result']
h5st = f"{dt[0:17]};{fingerprint};{appId};{token};{result2};5.1;{t};{pk};{a};{tenth_encrypt}"
print("h5st:"+h5st)
以前老版本还有sha512,现在只用到了base64、sha256、md5,fingerprint,appId,pk是固定的,token,salt,func_name是接口返回的,唯一棘手的地方就是这几个加密算法都是魔改过的,相信这个难不倒大佬们。
看一下效果把

友情提示:千万别用ai去还原这几个算法。

6751

被折叠的 条评论
为什么被折叠?



