某乎x-zse-96,关键点定位就不多说了,直接搜关键字都能定位到,直接进入正题。
简单说一下前面无关紧要的部分,MD5(101_3_3.0+url+d_c0)得到一个32位字符串(如果有x-zst-81字符串拼接的时候要加上+x-zst-81,但是似乎不加也没关系,这个还没有深入研究),传入encrypt函数得到最终结果,关键就是这个encrypt。
跟断点进入encrypt,然后调着调着就退出了,本次请求也没有拿到数据,因为他在new l的时候初始化了一个时间戳,后面通过控制流去判断时间,超过500毫秒,就被判定为调试,会直接结束返回0
解决方法:找到S赋值的地方,把S=this.U()改为S=this.a,或者直接把this.T -= 500 < S - this.a ? 24 : 8;这一句删掉也行。
做js文件替换时如果遇到了cors error,导致加载不了,可以在response headers中加一个Access-Control-Allow-Origin,这里我用的是charles
这里继续调试下去,不知要猴年马月才能看完一遍,一共循环了两万多次,于是跟着大佬学了一手日志断点逆推算法逻辑。
为了方便后面回溯,在替换js的时候加一个索引,以便于后面的条件断点
new l初始化完成后,就进入了这个大循环里,循环结束,返回最终结果。所以在这个循环的地方做日志断点(右键 - add logpoint)
"索引:", this.num, " 值:", JSON.stringify(this, function(key, value) {if (value == window) {return undefined} return value})
弄好以后,触发一次请求,这时控制台会打印出所有的日志,加了日志以后,速度会比较慢,这里耐心等一会,慢是正常的。运行结束,在控制台右键-save as,日志保存在本地,方便研究。
在日志里搜索最终的加密结果,可以发现,最终结果是一个字符一个字符拼接而成。
追到第一次拼接的地方,有三处关键点,一个神秘的字符串,一个关键的数字50,一个最终结果的第一个字符"b"。他们之间的关系是,字符串的下标50得到字符"b"。后面每一个拼接的字符都是这样的,而这个字符串也是不变的,所以只需要知道这个数字是怎么来的,就可以了。
寻找50最先出现的地方,在上一步索引14977打断点。重新打断点也会慢,因为有日志,但是日志又不能关,因为要做数据对比,虽然每次的值都随机了,但是运算逻辑不变,所以数值出现的规律也是一样的。
然后单步调试,一步一步看数值是怎么来的,通过调试和观察日志,发现数值是四个一组,通过& 63计算得到。63是个固定值,关键数字为 1799026,经过四次运算后1799026会改变。一共有16个数,一个数运算4次,再通过之前的字符串映射关系得到最后的64位结果。
按这个思路就可以完整复盘整个算法逻辑,后续已经发了。
至于x-zst-81算法,虽然也扣完了,但是经过测试,不需要也可以的