您现在的位置是:首页 >技术杂谈 >js逆向-某东h5st网站首页技术杂谈

js逆向-某东h5st

逆向新手 2024-06-14 17:17:46
简介js逆向-某东h5st

声明

本文仅供学习参考,如有侵权可私信本人删除,请勿用于其他途径,违者后果自负!

如果觉得文章对你有所帮助,可以给博主点击关注和收藏哦!

前言

目标网站:aHR0cHM6Ly9pdGVtLmpkLmNvbS8xMDAwNDc2MTIwNjAuaHRtbCNjb21tZW50

目标参数: h5st

参数分析

做爬虫最重要的事就是抓包,抓到想要的包之后发现某东新增了两个参数。
在这里插入图片描述
经过测试发现x-api-eid-token不是非必须校验参数,有兴趣得小伙伴可以自行分析。

接着看目标参数,可以看见该参数组成部分非常得多,肉眼可见的有时间戳得格式化日期和时间戳,其他的暂时不知。

全局搜索h5st发现意义不大,在这里主要采用xhr断点。
在这里插入图片描述

我这里选择的是getDataColor处打下断点,重新刷新页面后断点就断下了。
在这里插入图片描述
此时发现h5st已经生成了,向上跟栈查看哪里调用了该函数。
在这里插入图片描述
在这里插入图片描述
向上追了一层调用栈后发现此处出现了目标参数,依旧是打下断点进行分析。

跳到断点处,首先是将n进行json进行序列化和反序列化以便后续操作,然后进行sha256处理,看到then就知道是一个异步处理。

如果猜的不错的话,加密逻辑应该是放在了这个异步中,完成加密后赋值给n对象,此时就完成了参数的组装。

分析完成后分别看一下n、a.body是什么。
在这里插入图片描述
n是请求参数的一部分,body是哈希后的值,在后面生成h5st需要用到。

扣代码

分析完成后,就是扣代码了。对于异步的逻辑在跟值得时候经常后跟丢,在这里讲一个小技巧,遇到异步标识时使用F9去步入,这样可以有效的进入每一层,能够少走很多冤枉路。

单步进入发现在此处强行更改了this的指向,此处比较可疑。在这里插入图片描述

再观察一下arguments的值。
在这里插入图片描述
可以看到出现了加密后的body值,在这里就要打起十二分的精神了。此处绝对有问题!
this中的__genKey函数追进去,发现是一个字符串的拼接然后进行sha256的加密处理(此时的算法可能会有不同),通过函数名称可以得知生成了一个key,至于有什么用,暂时不得而知。
在这里插入图片描述
其中tk、fp、ts、ai、algo这五个值的由来分别是:接口处返回、浏览器指纹、格式化的时间戳、appid、加密库。

在这里插入图片描述
tk和fp可以写死,ts可以通过python处理。

继续跟栈,知道出现下图。

在这里插入图片描述
也就是h5st中的关键参数。
在这里插入图片描述
实际上核心逻辑在这里,还原后的结果如下:

s = rr['HmacSHA256'](a, n).toString();

在这里插入图片描述
a是之前的对象做了处理,body已经知道是sha256后结果,中间一串固定,最后是一个当前时间戳。
n就是之前__genKey的结果。

其实在这里要进行加密处理的是a,盐是n。

那么现在就清晰了,借用一下大佬的文章,里面说的很清楚。
链接: 2023年最新某东web端h5st算法分析

在这里插入图片描述

剩下的就是还原了,因为比较简单可以直接使用python去还原。

算法还原

代码不能直接使用,请自行修改。

# -*- encoding: utf-8 -*-
import datetime
import time
import hashlib
from hashlib import sha256
import hmac


class GenerateEncryptParams:
    def __init__(self):
        pass

    def get_key(self, date):
        """
        生成hmac256 盐值
        """
        str_ = f'tk03wc95a1c9d18nRYzC脱敏VWv5BmG2jYiq脱敏PWLit66JWj4ltExEI2b-wkXMyCLrv2b脱敏hvcMKYq脱敏脱敏4k9_yZl58380087754683脱敏{date}fb5dfpJxfS7yU脱敏脱敏'
        md5 = hashlib.md5(str_.encode())
        key = md5.hexdigest()
        return key

    def get_sign(self, data, key):
        key = key.encode('utf-8')
        message = data.encode('utf-8')
        sign = hmac.new(key, message, digestmod=sha256).hexdigest()
        return sign

    def get_encrypt_body(self, body,t):
        """
        加密params信息
        """
        sha256_ = hashlib.sha256(body.encode())
        encrypt_body = sha256_.hexdigest()
        data = f'appid:pc-item-soa&body:{encrypt_body}&client:pc&clientVersion:1.0.0&functionId:pc_detailpage_wareBusiness&t:{t}'
        return data

    def get_encrypt_info(self, body):
        t = int(time.time() * 1000)
        timestamp = t / 1000.0  # 将时间戳除以1000,转换为秒
        dt = datetime.datetime.fromtimestamp(timestamp)
        formatted_date = dt.strftime('%Y%m%d%H%M%S%f')[:-3]  # 格式化日期字符串,去掉最后三位微秒数
        key = self.get_key(formatted_date)
        data = self.get_encrypt_body(body,t)
        h5st = self.get_sign(data, key)
        return t, formatted_date, h5st


if __name__ == '__main__':
    g = GenerateEncryptParams()
    a ="{"skuId":脱敏脱敏脱敏,"cat":"脱敏脱敏","area":"7_549_558_34702","shopId":"脱敏脱敏","venderId":脱敏脱敏,"paramJson":"{\"platform2\":\"1\",\"specialAttrStr\":\"p0pppppppppp1ppppppppppppp\",\"skuMarkStr\":\"00\"}","num":1}"
    t, formatted_date, h5st = g.get_encrypt_info(a)
    print(t, formatted_date, h5st)
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。