作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
初步分析
我们先抓包看下x-s
长什么样子。
很明显x-s
是XYW_
加上一个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] = b2
而b2
刚好是178
的十六进制,而图中另一个208数组的77刚好就是178。由此我们可以看出加密结果是由这个208数组转十六进制之后拼接而成。
我们继续向上查看日志,寻找这个208数组的来源。
在向上查看的过程中,惊喜地发现有个256的数组长这样。如果你对加密算法有过研究,一眼就能看出,这就是AES
的S盒
,到这我们便可以初步确定这是一个AES算法了。既然是AES算法,那肯定有key
和iv
。继续向上看日志。
往下查看日志,发现在对两个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
一样(●’◡’●)
结果演示
接下来编写代码调用接口测试能否成功请求
算法获取以及相关问题可以私聊作者交流~