【JS逆向】2024年9月20日-小红书最新x-s算法还原

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!

初步分析

我们先抓包看下x-s长什么样子。

在这里插入图片描述

很明显x-sXYW_加上一个JSON格式字符串的 Base64编码,我们来解码看看原始文本是什么。

在这里插入图片描述

{"signSvn":"55","signType":"x2","appId":"xhs-pc-web","signVersion":"1","payload":"31e72e37c22408bd6ef26b0dc7a900a097d7e43b0f7c42fea858bcb9ce2959af1085070b7c69939302fb45af46dd33e67c594e165ae05e4df9208f24769d509c41858c5fe82146e8428f54b8ddb21ff6b7ac10bba9646577c56d67bd441f45d32878667fa67b185f568b665797657dbfc575d037fb9d3004961f645a109648c5ebd4e06ddf01702ecee5c23e15352f441c85b4222eb907c9063ea5ea34443793985706ed60dc2b309f1a678c1f695200c1feb8821220ee5a32d980c15c9250d7db3f2e61b378216dd5e0796f9c701d3c"}

可以看到只有payload字段是加密了。接下来我们在JS代码中定位到x-s的生成位置。打开F12,搜索"X-s",在这里打上断点。

在这里插入图片描述

跟进window._webmsxyw函数,可以看出这是一个VMP,通常我们有两种解决办法:补环境、插桩还原算法(ps:这里函数被加载到window对象上,我们也可以采用rpc的方法来调用)。

在这里插入图片描述

插桩分析

插桩的位置有很多,大家可以自己尝试,这里就不给出具体的位置了。

在这里插入图片描述

可以看出加密结果被放在一个208的数组里,最后调用join方法拼接而成,我们向上查找日志,看看这个208数组是怎么来的。

在这里插入图片描述

这里可以看到,[77] = b2b2刚好是178的十六进制,而图中另一个208数组的77刚好就是178。由此我们可以看出加密结果是由这个208数组转十六进制之后拼接而成。

在这里插入图片描述

我们继续向上查看日志,寻找这个208数组的来源。

在这里插入图片描述

在向上查看的过程中,惊喜地发现有个256的数组长这样。如果你对加密算法有过研究,一眼就能看出,这就是AESS盒,到这我们便可以初步确定这是一个AES算法了。既然是AES算法,那肯定有keyiv。继续向上看日志。

在这里插入图片描述

往下查看日志,发现在对两个16数组进行循环异或操作。

在这里插入图片描述

这里我们可以看到有个新的208数组,取出前16位,与另一个16位数组进行异或,多次刷新,这个异或数组不变,于是我们大胆猜测这就是我们要找的iv。由于key的分析过程较为漫长,但思路是一样的,这里就不再叙述,感兴趣的朋友可以自己尝试分析。

接下来我们分析明文的构成。

在这里插入图片描述
在这里插入图片描述

这里可以看到在将一个字符串转换为数组,而这前几位正好对应我们上面看到的新208数组,不难想到,这个字符串就是我们要找的内容,继续向上查看日志,看看这个字符串怎么来的。

在这里插入图片描述
看到这里相信有的朋友一下就知道了,这串字符串就是下面x1 x2 x3 x4字符串Base64编码生成的

在这里插入图片描述

'x1=ad8cdf1c752642088073c5f67a0cfc78;' // hash加密 盲猜md5
'x2=0|0|0|1|0|0|1|0|0|0|1|0|0|0|0|1|0|0|0;' // 检测什么东西生成的(应该可以写死)
'x3=1920905cb73t8qsfkhoomdhscvlvjuf1vk28kyzdt50000258714;' // 不知道什么玩意
'x4=1726815250907' // 时间戳

继续往上看日志、看日志、看日志、看日志、看日志、看日志、看日志

在这里插入图片描述
找到对x1进行拼接的日志了,继续往上~

在这里插入图片描述

hash算法,继续往上~

在这里插入图片描述

我们试试将url=/data/sem_sdk进行md5加密,结果与x1相同

在这里插入图片描述

接着我们继续往上,看看能不能找到x2、x3的线索

在这里插入图片描述
x3也找到了,是cookie中的a1

在这里插入图片描述

x2与猜测一致,19个函数对环境进行检测,直接写死即可~

至此,我们的分析就结束了,接下来进行算法还原

算法还原

var a1 = '19208186a74oe93v9l3c3vdnvh8r5g3pb4tnvunji50000172643',
x1 = md5(url + JSON.stringify(data)),
x2 = '0|0|0|1|0|0|1|0|0|0|1|0|0|0|0|1|0|0|0',
x4 = +new Date();

var payload = aes(btoa(`x1=${x1};x2=${x2};x3=${a1};x4=${x4};`), key, iv),
xs = 'XYW_' + btoa(JSON.stringify({"signSvn":"55","signType":"x2","appId":"xhs-pc-web","signVersion":"1","payload": payload}))

最后将算法还原也就80行代码,我们将日志中的值代入,计算看看结果是否一致

在这里插入图片描述

出值成功,看起来和上面的payload一样(●’◡’●)

结果演示

接下来编写代码调用接口测试能否成功请求

在这里插入图片描述

算法获取以及相关问题可以私聊作者交流~

### 解析 Import Error 的常见原因 当遇到 `ImportError: cannot import name 'Generic'` 错误时,通常意味着尝试从模块中导入的对象不存在或无法访问。此问题可能由多种因素引起: - 版本不兼容:不同库之间的版本冲突可能导致此类错误。 - 安装缺失:目标库未正确安装或路径配置有误。 - 导入语句不当:可能存在循环依赖或其他语法层面的问题。 ### 针对 Generic 类型的具体解决方案 对于特定于 `Generic` 的情况,考虑到 Python 中 `Generic` 是 typing 模块的一部分,在处理该类别的 ImportError 时可采取如下措施[^1]: #### 方法一:确认typing模块可用性 确保环境中已安装标准库中的 typing 模块,并且其版本支持所使用的特性。可以通过以下命令验证: ```bash python -c "from typing import Generic; print(Generic)" ``` 如果上述命令执行失败,则可能是由于 Python 或者相关扩展包的版本过低造成的。此时应考虑升级至更高版本的解释器以及对应的开发工具链。 #### 方法二:调整导入方式 有时直接通过顶层命名空间来获取所需组件会更稳定可靠。修改代码以采用这种做法可能会解决问题: ```python from collections.abc import Iterable # 如果是迭代器相关接口 from typing import TypeVar, Protocol # 对于协议和泛型定义 T = TypeVar('T') class MyContainer(Protocol[T]): ... ``` 注意这里并没有显式提到 `Generic` ,而是利用了更为基础的数据结构抽象基类或是其他替代方案实现相同功能[^2]。 #### 方法三:排查环境变量设置 检查系统的 PYTHONPATH 和虚拟环境配置是否正常工作。任何异常都可能导致某些第三方软件包找不到必要的资源文件而引发类似的错误提示。建议清理并重建项目专属的工作区以便排除干扰项的影响。 #### 示例修正后的代码片段 假设原始代码试图这样引入 `Generic` : ```python from some_module import Generic # 可能导致 ImportError ``` 改为遵循官方文档推荐的方式后变为: ```python from typing import Generic # 正确的做法 ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值