知乎x-zse-96参数分析详解

知乎的首页加密就这一个,流程比较简单,带大家全流程逆向x-zse-96这个参数

重新发一遍,之前那个流程我只补了一个window,然后我就去试了一下首页,结果是能拿数据,还以为自己补对了,其实是服务器根本没验,前几天有粉丝找上来让我爬评论,结果一试发现不行,然后我马上就把这篇文章下了.

现在有空重新梳理一下流程,前面几部都大差不差,关键是后面函数的补环境.

知乎x-zse-96参数分析详解_第1张图片

 网址:aHR0cHM6Ly93d3cuemhpaHUuY29tLw==

目录

篇幅较长,坐稳发车咯!

声明 

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

x-zse-96参数分析

总结


篇幅较长,坐稳发车咯!

声明 

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

x-zse-96参数分析

1打开知乎首页,往下滑,先抓一个包

知乎x-zse-96参数分析详解_第2张图片

2载荷里没有加密, _token应该是一个token令牌,维持登陆的

3再来看头部,多翻几页可以发现x_zse_81是不变的,可以先固定,另一个参数x_ab_pb也可固定

知乎x-zse-96参数分析详解_第3张图片

4先全局搜索x-zse-96,不行的话可以hook头部或者下xhr

5可以发现能搜索到两个,全部打上断点后往下滑,断住后把另一个取消掉

知乎x-zse-96参数分析详解_第4张图片

 6控制台输出一下,发现就是这个结果,此时只需要分析E,可以往上找

知乎x-zse-96参数分析详解_第5张图片

7控制台输出一下可以发现E就是这个加密的结果

8从内到外一次输出结果,可以发现是f()这个函数加密s成32位的密文再经Z(r).encrypt加密成最终结果的,32位可以先尝试一下是不是md5,验证一下发现是标准的md5

9  c4c是经典的md5加密字符串1,这样就可以省去扣算法的时间了

10接下来分析s,全部补上后发现少了V这个方法

var o = "101_3_3.0"
, i = "AGDYBfhvGBaPTn-gL72IY3suWqNIoKC34tE=|1672377086"
, a = "3_2.0aR_sn77yn6O92wOB8hPZnQr0EMYxc4f18wNBUgpTQ6nxERFZBXY0-4Lm-h3_tufIwJS8gcxTgJS_AuPZNcXCTwxI78YxEM20s4PGDwN8gGcYAupMWufIeQuK7AFpS6O1vukyQ_R0rRnsyukMGvxBEqeCiRnxEL2ZZrxmDucmqhPXnXFMTAoTF6RhRuLPF03CYCo8bUr8JCxKIGoBpJL_0qCqoTcOhDVY2Cwf2AHmrT29nwwf_vNGODoTvMSL_JL_yhp9bLH1riwLgDoCurXOXhH9EhSskggLfXL82UHqXD3OtDe_RBN0SALLkUxLAcH_8_oM0gVCICt8-upfg9w0LJSCP9cKTwN1s0N_QiU_LJSxCqfz10XL0JOykGHLeiO06DNBogo10BgMfBLmTuFMHbeMuwO_0GY_BRo_0cpCNqtpSXCGKDxmquOm2B3KYCwYKC2m-hOGLUpY9Gg_Twe919LqF9LYwheLuBCC"
, u = "/api/v4/commercial/ecommerce"
, c = '{"urls":["https://xg.zhihu.com/plugin/c8aa5b5253475b97fd4c8696ae6d3cd8?BIZ=ECOMMERCE","https://xg.zhihu.com/plugin/c8aa5b5253475b97fd4c8696ae6d3cd8?BIZ=ECOMMERCE"],"type":"answer","os":"other","url_token":"2721767583"}'
, s = [o, u, i, V(c) && c, a].filter(Boolean).join("+");

11把V补上后可以发现s可以生成

V = function(t, e) {
            return void 0 === e && (e = 4096),
            !!t && function(t) {
                return new Blob([t]).size
            }(t) <= e
        }

12接下来就是扣Z(r).encrypt这个方法了

13进去这个方法发现它是属于一个模块内部的方法

14往上找把整个模块扣下来在node里调试

知乎x-zse-96参数分析详解_第6张图片

15直接把加密的值传进去再调用就行了知乎x-zse-96参数分析详解_第7张图片

16运行一下应该会报一个__g._encrypt不是一个方法,其实是缺少了浏览器环境导致js走错了

这里我用的是jsdom补环境,需要安装jsdom这个库,直接调用npm命令就行了

npm install jsdom

17再补上以下环境,不要直接粘贴,把地址换了 

const dom = new JSDOM(`

Hello world

`,{url:"https://www.脱敏.com/"}); window = dom.window location = window.location navigator = window.navigator document = window.document; history = window.history; screen = window.screen;

18补完发现可以生成结果,但是带上这个参数的请求是拿不了数据的,还缺了环境 

19回到浏览器里,可以发现多次加密同一组数据竟然结果不同,可能是时间戳,也可能是随机数,试着hook了一下随机数,发现结果不变了,证明是随机数的问题,可以在node里hook随机数再调试,直到出现和浏览器一样的结果

20直接运行结果不一样,也没有任何提示,可以加上proxy代理再调试,代理我补瑞数的时候有讲

21这里断在了document.toString这个方法,浏览器里返回的是'[object HTMLDocument]',node里返回的是[object Object]

22可以在原型里修改这个方法

let xxx = Object.prototype.toString
Object.prototype.toString = function () {
if(this.constructor.name === 'Document') {
  return '[object HTMLDocument]'
 }
return xxx.call(this, arguments)
}

23可以发现这个错误解决了,但结果还是不对

 24请提前安装canvas这个包,不然会报少包的错误,尽量使用这个命令,普通的npm命令可能装不上

npm install canvas --canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas

25装好后把以下代码加到上面的if的后面

else if(this.constructor.name === 'CanvasRenderingContext2D') {
  return '[object CanvasRenderingContext2D]'
}

26再次运行断在了window._resourceLoader,浏览器里是undefined,把这个补上后再次运行

27刚才那处已经过了,这次断在window._sessionHistory,浏览器也是undefined,接着补上

28断在了global这里,node的全局变量是global,浏览器里面没有global,参考了一下其他大佬的文章,应该是缺了一个alert = window.alert

29旧版本的有这个报错提示,新版本的好像没有

再次运行,断在了__proto__

30这里其实是再次对tostring进行了了检测,打印一下发现是大Window的问题

let aaa = Function.prototype.toString
Function.prototype.toString = function () {
    console.log(this)
    console.log(aaa.call(this,arguments))
return aaa.call(this, arguments)
}

31浏览器返回的值

32补上最后的环境

let aaa = Function.prototype.toString
Function.prototype.toString = function () {
    console.log(this)
    console.log(aaa.call(this,arguments))
if(this.name === 'Window') {
  return 'function Window() { [native code] }'
}
return aaa.call(this, arguments)
}

33补完这个发现结果是一模一样的

34带上这个参数发现可以正常拿到评论结果

总结

1出于安全考虑,本章未提供完整流程,调试环节省略较多,只提供大致思路,具体细节要你自己还原,相信你也能调试出来.

2本人写作水平有限,如有讲解不到位或者讲解错误的地方,还请各位大佬在评论区多多指教,共同进步.技术探讨加v lyaoyao__i(两个_,本人)

3本篇分享到这里就结束了,欢迎大家关注下期,我们不见不散☀️☀️

你可能感兴趣的:(js逆向,python,javascript,前端,pycharm,安全)