知乎评论爬取——x-zse-96参数逆向分析

616 阅读8分钟

参数分析过程:

1️⃣本案例既可以采用跟栈分析,也可以直接使用关键字搜索

跟栈分析:

首先打上offset的XHR断点,因为知乎评论的请求链接都含有offset参数,当然也可以使用order_by、limit等参数

刷新页面,最后在如下图所示的位置进行debugger

​编辑

接着采用跟栈分析的方法,一点一点的往上查看堆栈的作用域,查找我们所需要的加密参数的形式

​编辑

在这个调用堆栈查找到了我们所需要的已经加密的参数,

​编辑

继续往上查找调用的堆栈的作用域,寻找加密参数在哪里发生变化:

​编辑

​编辑

可以发现在这两个堆栈之间加密参数发生了改变(相对于之前的加密参数缺少了2.0_),肯定在这两个堆栈之间发生了对加密参数的处理操作,寻找一下具体的处理方式如下:

​编辑

可以发现经过这一步操作,参数由无2.0变为有2.0,做了一个字符串的拼接,其中参数t2便是固定值2.0,t0便是我们所需要的加密参数,继续向上溯源

​编辑

可以发现,t0是tT的signature属性,而tT又是通过ed函数得到,第一个参数是te

​编辑

是我们的请求的网址,其中639580298是文章的ID,第二个参数tf.body是undefined

​编辑

第三个参数是一个对象,由zse93:tb(固定值“101_3_3.0”),dc0:tS,xZst81:tC(固定值null)

其中tS是也是一串密文,向上溯源,发现:

​编辑

步入er函数:

​编辑

发现t9是一个正则的匹配对象,er函数即是对document.cookie进行一个正则的匹配(匹配的规则便是t9)

​编辑

到此,那么函数ed的参数tS也解决了,最后一个参数便是tA:

​编辑

tA也是undefined,多次刷新,最终的值也是undefined,那么就可以步入到ed函数中查看执行过程

​编辑

可以发现signature参数最终是由(0,tJ(ti).encrypt(ty()(tp)))生成,在控制台打印一下是否是加密参数的生成位置:

​编辑

由于笔者重新刷新了一下,这里的加密与上面的加密参数不是相同的。多次在控制台打印

​编辑

发现加密的参数会变化,这里一般有两种原因(随机数或者时间戳)

​编辑

固定一下时间戳,发现加密参数还是没有固定,那么再试着固定一下随机数

​编辑

发现固定了随机数以后加密的参数就不变了,那么需要排除一下是否有时间戳的影响(同时固定时间戳和随机数)

​编辑

发现加密参数并未发生变化,则可以排除时间戳的影响,本例中只有随机数。

​编辑

​编辑

继续分析这个加密函数的参数,其中tp是由ta,tf,tu三个拼接而成,ta:"101_3_3.0",tf:"/api/v4/comment_v5/articles/665262969/config",tu:"AeAamiPucRiPToBPuktmMVxXgcWwR0TAU80=|1712742588"

分析得出:ta是固定值,tf即是参数te截取了一部分,tu即是由er()函数生成的tS

​编辑

ty()tp首先生成了一次加密,看起来像是md5加密(位数为32位),在线md5看看是不是标准的md5机密

​编辑

可以看到是标准的小写md5加密

那么便只有tJ(ti).encrypt函数需要解密

​编辑

步入到这个函数中,发现一个g. encrypt,且下面是一个exports导出,发现是一个webpack打包的

那么只需要找到webpack打包的三要素(加载器,模块,环境)即可还原出D函数

​编辑

显然这个文件就是模块,那么只需要找到加载器和最后补好浏览器环境即可,显然

​编辑

tJ(ti)便是起到加载器的作用,继续溯源

​编辑

可以看到tv便是加载完成的模块

​编辑

可以看到tv是由tr函数加载过来的,继续溯源

​编辑

很明显这是一个webpack加载器,最后只需要补环境即可

分析完成,接下来便是扣js代码了

直接创建三个js文件,env.js,mod.js,loader.js

将刚刚找到的加载器的js文件和模块的js文件全部复制进loader.js与mod.js中

按顺序导入相应的js文件

​编辑

在env.js文件中创建一个load = {}对象,并在loader.js中的加载器函数下设置

​编辑

用来获取加载器

通过前面的跟栈分析可以得出,需要加载的模块为1514,在process.js文件中调用加载器加载1514模块,并对数据进行解密

​编辑

运行以后会报self is not defined的错误,只需要将mod.js与loader.js文件中的self改成window即可,运行以后得到加密结果

​编辑

与我们所需要的加密结果对比:

​编辑

显然不是我们所需要的加密结果,那么就是环境的问题了

首先在env.js文件中设置window对象的代理:

​编辑

运行程序:

​编辑

发现window对象并没有缺失,那么就只可能是其他对象缺失,我们把浏览器常见的对象都进行补充并监听

document、location、history、navigator、screen等进行补充和监听

运行程序:

​编辑

navigator对象缺失了userAgent,我们对其进行补充,回到浏览器进行查看

​编辑

​编辑

继续运行程序:

​编辑

发现document对象缺少了一个toStrin方法:回到浏览器查看并对其进行补充

​编辑

​编辑

接下来几步基本一致,根据提示信息需要将所有的补充的对象补充toString 方法

​编辑

如上图所示进行补充,继续运行程序:

​编辑

发现调用了document对象的createElement方法,我们对其进行补充,查阅文档发现他会创建一个对象,创建一个element对象并对其进行监听,发现他是一个调用了element对象的getContext方法,查阅文档发现会返回一个CanvasRenderingContext2D对象,对其进行补充并监听

​编辑

​编辑

​编辑

最终发现调用了一个toString方法,回到浏览器查看并补充

​编辑

​编辑

最终并未发生undefined等问题,但是得到的结果还是不符合要求,猜想是报错被捕获了

找到mod.js文件,删除对应的捕获的语句

运行程序:

​编辑

发现alert方法没有,在window全局变量加上即可

window.alert = funciton(){}

执行程序,

​编辑

补了document.getElementById方法与document.getElementsByClassName方法

执行程序:

​编辑

发现缺失了location.href,去浏览器找到并补充

​编辑

得到最终的加密结果:

​编辑

​编辑

得到了这个加密函数以后,最后只需要从

​编辑

引入标准的小写md5加密,对其进行加密即可

​编辑

最后在python中调用这个js文件即可解密

所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用,并严格遵守相关法律法规,如《中华人民共和国网络安全法》。作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。

文章中涉及的程序或方法仅供安全研究与教学之用,严禁用于非法目的,如未经授权的入侵、破解等。若读者将信息用于其他非法用途,由读者承担全部法律及连带责任,相关方不承担任何责任。

未经授权使用文章中的技术资料对任何计算机系统进行非法操作,由此产生的直接或间接后果和损失,均由使用者本人负责。