某乎 搜索接口逆向

**在此声明:**本文章仅仅用于学习交流,不得用于商业活动。

**本文篇幅较长,介绍的较仔细,适合新人观看**

目录

前言

一、总体思路

二、express介绍

1. Express简介

2. Express搭建

三、websocket 介绍

四、某乎 搜索接口分析

1、参数分析

1. X-Zst-81参数分析

一、 明文分析与实现

二、 明文加密分析与实现

2. X-Zse-96参数分析

一、 明文分析与实现

二、 明文加密分析与实现

2、利用websockets获取参数以及接口数据获取

总结


前言

众所周知,某乎的x-81 x-96参数,全是由jsvmp加固生成的,而对于jsvmp加固,通常都有3种解决方法:1.分析算法,插桩    2.补环境,一般都需要稍微分析代码,当然还有自动补环境代码,比如v神插件也可以乱杀某乎 3.rpc导出  

很多大佬都写过 补环境和分析算法的教程,我们就来玩点特殊的 (基于express和websocket)补环境 

一、总体思路

一般补环境都是缺什么补什么,模拟浏览器的环境来执行js文件

而我开启一个网站 把js放在里面,直接使用浏览器自带的v8环境 也能够解决问题,而且这个思路还能够解决如瑞数,akamai等一类较难的js逆向的网站。

当然这样补环境也会变得更加麻烦

二、express介绍

1. Express简介


官网对这个框架的解释是:基于 Node.js 平台,快速、开放、极简的 Web 开发框架。Express的官网地址是https://www.expressjs.com.cn 。

Express的特色:
(1) Web 应用程序:Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。

(2) API :使用您所选择的各种 HTTP 实用工具和中间件,快速方便地创建强大的 API。

(3) 性能 :Express 提供精简的基本 Web 应用程序功能,而不会隐藏您了解和青睐的 Node.js 功能。

(4) 基础框架 :许多 流行的开发框架 都基于 Express 构建。
 

2. Express搭建

基本代码如下:

const express = require('express')

const app = express()

const port = 5001



app.get('/',(req,res)=>{
    res.send('Hello world!')

})


app.listen(port,()=>{
    console.log(`启动于 127.0.0.1:${port}`)

})

这段代码可以在本地开启一个服务器 

可以访问网址127.0.0.1:5001 看到开启的服务端

三、websocket 介绍

websocket 是一种全双工通信 实现前端和后端的数据交流

基本代码这里就不展示了 网上很多教程。

四、某乎 搜索接口分析

网址:  aHR0cHM6Ly93d3cuemhpaHUuY29tL3NlYXJjaD90eXBlPWNvbnRlbnQmcT0lRTUlODglQkIlRTYlOTklQjQ=

接口:

https://www.zhihu.com/api/v4/search_v3?gk_version=gz-gaokao&t=general&q=%E5%88%BB%E6%99%B4&correction=1&offset=0&limit=20&filter_fields=&lc_idx=0&show_all_topics=0&search_source=Normal

1、参数分析

观察接口,可以看到也只有头部有加密,一共有两个参数加密 X-Zst-81 X-Zse-96

X-Zst-81 同一个页面请求值不变,能够写死,但是我喜欢写活,需要逆向

 X-Zse-96每次请求都不一样,需要逆向

可以采用全局搜索看看这两个参数究竟是哪里加密的

可以看到 X-Zst-81和X-Zse-96是在这里赋值的,但是不知道值是在哪里生成的,直接跟栈走看看值在哪生成,但跟栈走没有看到明显生成值的地方,可以搜索关键字 3_2.0 

1. X-Zst-81参数分析

一、 明文分析与实现

可以看出 这个就是 X-Zst-81的值  是由u[L("0x1a2")](z, x) 生成的,可以看[L("0x1a2")](z, x)内部是什么样的 

那么就清晰了

u(x)返回的值,x是明文值,通过u方法生成了X-Zst-81的部分值,再拼接"3_2.0"最后得到结果。可以往上找x这个明文值是哪里来的 

拼接这三个值得到x的明文值

接着往上找这三个值在哪里

找到位置了 可以进入函数里看看

其他几个值同理

所以x参数是window.localStorage中的 osa值

       d参数是document.cookie中的      osd值

        ea搜索可以找到是y函数生成的  进函数内部后 可以看到math.random 我们直接把y函数扣下来模拟加密

然后模拟明文参数的生成逻辑 将 x 拼接 # d # ea ,最后得到明文完整的明文参数。

二、 明文加密分析与实现

明文参数解决了,关键来了,看看它是如何将明文参数变成密文参数的,进入u函数内部

一共三个关键点,第一个我们可以看见有一大串字符串,这就是jsvmp其中之一的特征,一般有一大串字符串的或者数组(小红书)都可能是jsvmp;

第二个80177明显就是webpack 这个就不解释了,可以百度;

第三个就是可以看到它是通过__g._e2(encodeURI(u))得到的结果

直接开始扣代码

可以看到报错了,这是因为没有补环境,缺少环境导致报错的。

一般的补环境方法现在就可以用自吐环境方法开始补环境了,同时得去稍微看下js里代码运行需要哪些环境,这里给出一部分某乎检测的几点:window以及其原型链 navigator以及其原型链 Buffer等等

我们特殊点的补环境

利用express把代码放进浏览器中的v8环境运行

代码部分如下

如图 可以看到参数生成成功,且与知乎x-81 结果一模一样(有段随机数所以有点小变化,总体一样)

至此X-zst-81参数解决

2. X-Zse-96参数分析

    回到之前,看看X-Zse-96是在哪里生成的

X-Zse-96是tO值,而tO是ti.signature的值,ti是由函数ed加密几个参数生成的

一、 明文分析与实现

       第一个参数te,是接口网站拼接载荷

第二个参数tf.body undefined

第三个参数是一个对象,里面tb是定值,dc0是cookie里面的dc0的值,xzst81是刚刚解决的密文值

第四个tA是 undefined

二、 明文加密分析与实现

进入函数ed

tp是上面几个参数用+拼接而成

结果:tJ(ti).encrypt(ty()(tp))

而最后的结果就是由encrypt()传入ty()(tp)加密的

ty()(tp)值的长度32位,一般这个都是md5加密

验证一下,发现结果一模一样

还剩encrypt函数,进入内部看看

和x81一样的 也是jsvmp,我们按照同样的方法扣代码,然后 模拟加密 方在 express里面执行。

代码和结果如下:

同时这个代码同样会报错,也如同上面介绍的一样缺环境

把代码用express放在浏览器中运行,同时根据上面的逻辑,最后写成一个文件

可以看到浏览器中能够输出正确的值

2、利用websockets获取参数以及接口数据获取

那么我们传递给python使用呢?,我们选择websockets

建立python和网站的通信传递结果

如上 我们在代码中加入了websockets的服务端代码,使用websockets传递参数

而我们也需要在python端写一个客户端代码,用于获取服务端传递的数据,同时利用这个参数对网站进行请求,然后获取结果

客户端标准脚本如下图

如图

我们能够正常的获取结果

                                                        


总结

本文采用模拟浏览器的方法来补环境决某乎的参数 当然这肯定不是解决知乎最好的方法,对于解决某乎还有好多的方法。

肯定有人会说这样子写不如rpc,确实,从速度方面确实比rpc慢,但是比rpc更加便捷,不需要去每次都找加密点去注入,而且这种方法过瑞数很有效,仁者见仁,智者见智,技多不压身学会更多的方法遇到各种网站就能随便解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值