某乎请求头签名算法分析
本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
前言
-
小小白在这里给各位大佬拜个年了,祝各位大佬新年快乐,大吉大利,身体健康,技术更上一层楼
-
本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
网站
aHR0cHM6Ly93d3cuemhpaHUuY29tL3NlYXJjaD90eXBlPWNvbnRlbnQmcT1weXRob24=
加密定位
需要分析的接口以及加密参数 x-zse-96 如下图
直接搜关键字 x-zse-96,发现一个文件,点进去
格式化后再搜索 x-zse-96,发现两个可疑入口,分别是这两个
重新刷新网站,可以看到断点断在下图这个地方,选中执行函数可以发现加密入口就是这里
加密分析
s 明文数据:
s = '101_3_2.0+'(版本号) +
'/api/v4/search_v3?t=general&q=python&correction=1&offset=0&limit=20&filter_fields=&lc_idx=0&show_all_topics=0&search_source=Normal+'(接口后缀) +
'"AIAf1GdgbRSPTtoYPsJrpvRp_MB-_8SxwGQ=|1643717522"'(dc0 cookie)
第一层加密
l()(s) = '7dd6414484df2c210ddbb996c55cf64c' -> md5_str
根据 js 逆向的一些小经验,32 位密文很容易想到 md5 签名加密,拿到在线 md5 加密测试网站去试试
perfect,完美对应上,由此可知,第一层加密就是原生的 md5 加密
第二层加密
a()(md5_str) = 'a0xqSQe8cLYfSHYyThxBHD90k0xxN9xqf_tqr6UqH9Op'
选中 a(),点进去,会进入到这个函数,加密参数正是第一层加密得到的 md5 字符串,如图所示
然后就单步跟,跟到这里就先别跟了,这里正是 jsvmp 循环一条条执行指令的地方,下面的代码会根据时间来检测调试
然后就在 35865 行打上 log 输出断点,把 this.C 索引值跟 this 对象里面的值都给打印出来,注意要把 window 除去,不然会缺数据,索引值方便后序调试可用
"索引:", this.C, " 值:", JSON.stringify(this, function(key, value) {if (value == window) {return undefined} return value})
慢慢等待输出结束,掉头发的逆向之路就可以开始了
直接在输出的 log 日志里面搜索加密生成的密文
这个 vmp 生成的加密参数是分成 11 组来计算的,每 4 个一组
这里面有一个固定不变的字符串,就是这个玩意
fix_str = "RuPtXwxpThIZ0qyz_9fYLCOV8B1mMGKs7UnFHgN3iDaWAJE-Qrk2ecSo6bjd4vl5"
拿第一部分 a0xq 举个例子,看看他是如何生成的,其他的都差不多
fix_str[13] = ‘q’
q 就是这样来的,每一个字符都是通过索引那个固定字符串得到的,所以,接下来,就该来寻找索引下标是怎么生成的,向上寻找,看到这个
3433258 » 18 = 13
这里的 18 是固定的,其实判断是不是固定的数字,只需要对比两个控制台里面 log 输出的对应分析就可以很清楚的知道哪些是固定不变的了
再来搜索 3433258 这个数字怎么来的
可以很清晰的看得到,下面这几种运算都可以得到这个数字,那怎么判断是哪一种运算得到的,我的办法是:调试
1. 25386 + 3407872 = 3433258
2. 25386 ^ 3407872 = 3433258
3. 25386 | 3407872 = 3433258
重新打开一个浏览器打开链接,在 log 输出相同地方换上一个条件断点,断点的条件是 this.C = 342,具体跟进去看看他到底是进行的什么运算
这里这一步我就直接说了,是第三种,| 运算得到的,知道运算符之后,又要去分析两个参与运算的值是怎么得到的,这里就需要慢慢去一步步去逆向搜索分析了,所有参与运算的值都可以用这种同样的方法搜索分析得到
这部分所有的运算流程都在下面了,请各位大佬们自行慢慢对比 log 输出去参悟,理解
最后验证:
可以发现,算法还原下来只有短短的 50 几行,而且最后本地生成的加密参数跟浏览器生成的完全一致,完结撒花