如下内容仅交流学习,请勿用于非法用途html
若是你如今想模拟登录知乎,会发现 fromdata 是一串加密的字符串node
看了以后是否是很痛苦?你是否是就想使用 selenium 来模拟登录?不过好像知乎对 selenium 也进行了相应的反爬处理,哈哈。可是我不也想用 selenium,效率太慢了,直接破解 js 才是我最喜欢挑战的。好,我如今教你如何用 js 硬撸破解,废话很少说,直接进入正题。python
1. 找出signature加密
加密位置这个相对来讲是比较难找的,须要本身对那些混淆过的 js 进行一遍又一遍的搜寻,有时候你看到头皮发麻也不必定找获得,再加上这个加密参数是一堆字符串,连个键都没有,搜索的条件都没有。这怎么办呢?咱们能够去百度或者谷歌看看前人是怎么搞的。web
你直接搜索知乎模拟登录的话,会发现之前的知乎的 fromdata 是键值形式的,有如下键值对算法
顺便也能够看看以前的破解思路,看到了上面的 signature 是经过加密来的,猜想知乎应该也是对以前的键值加密的 fromdata 进行加密的,在控制台搜搜 signature 看看有没有线索api
提示:按下 ctrl + shift + f 可出现搜索框浏览器
一搜,果真有,看了看,signature 的加密过程和之前的仍是同样的,证实个人猜测正确了,说明是经过以前的 fromdata 的键值对进行加密成的一堆字符串,如今就看看 signature 是如何加密的。微信
若是你对加密有点了解的话,还容易知道经过上面代码知道,很容易知道是经过 hmac 加密,哈希算法是 sha1,密钥为 d1b964811afb40118a12068ff74a12f4,加密数据有四个,为 clientId、grantType、timestamp 和 source,这些值均可以在上面经过调试出来的,就很少说了,以下cookie
2. 找出fromdata的完整键值对
在知道 signature 是如何加密的以后,咱们还须要找出完整的 fromdata 先,不过在上面的调试中,你会发现也有几个 fromdata 值,可是不全。webstorm
这时候若是咱们得继续搜索 signature 的话,找了一成天你都会发现不到什么线索,这时候咱们能够经过登录的 url 进行突破,看看 url 是哪一个路径,而后一段搜。
其登录url是 https://www.zhihu.com/api/v3/oauth/sign_in。那咱们能够直接搜 sign_in 试试。搜了发现和上面的 signature 是在同一个 js 文件上的,感受应该有戏。
这个和登录地址彻底匹配,应该就是这个了,能够进行调试一波
这不出来了,通过屡次调试,发现大多数值都是固定的,只有 signature 和 timestamp 不是,其余的就是帐号密码之类的,还有个验证码 captcha 以及它的类型 lang,signature 上面的已经找出来了,timestamp 很明显就是时间戳,其余的就很少说了。
如今的 fromdata 已经所有找出来了,咱们离加密字符串又近了一步,若是你直接用这个表单进行模拟登录,会给你返回下面错误
Missing argument grant_type
可见咱们还得找出这个 fromdata 的加密方法。
3. 找出 fromdata 加密位置
若是你是第一次找这个,估计你得不断地翻 js,也不必定能找获得,或者你能够根据下面这个调用函数过程来找
会发现不少,不过你懂套路的话都知道加密通常都用到 encrypt 名字之类的,能够直接根据这个名字搜
一搜果真有这个,经过查看你很容易就找到这个
这个一经过调试,你能够看到,咱们的加密字符串出来了,是否是很激动,我当时找到了这个的时候激动不得了。
这个是加密的字符串
这个就是咱们须要找的
历尽千辛万苦,终于找出了庐山真面目,激动不?先不要激动先,这只是加密的位置,后面的才是最难的!
4. 找出 fromdata 加密的全部方法
知道位置后,咱们能够直接把这个加密的 js 方法都扣出来,放在一个 html 文件内执行就好。
在上面找出位置以后,很容易就能够看到这个完整的一个的加密方法
按这个半括号向上找,你就能够找到一个完整的加密方法,这个就是整个 fromdata 的加密方法,挺容易找的,若是以为不方便找的,能够先将这个 js 文件里面的代码复制下来,而后到 Sublime Text 软件上找,这个能够折叠,也比较容易找,找出来是这样子
格式化以后有 400 多行,并且全是混淆,难看得一批。
为了看看这个正确不正确,咱们能够把函数里面的内容直接拿出来,就是去掉最外层的函数,而后调用下面的函数 Q,把咱们的 fromdata 传进去
最后将上面的 JavaScript 给弄成一个 html 文件,放在 script 标签内便可
格式就和上面同样,而后直接用浏览器上打开这个 html 文件,你会看到这个
这个就是咱们一直努力在找的 fromdata 加密字符串。
弄完这个以后,咱们继续使用 python 来操做了,由于这个 加密的方法格式化以后有 400 多行,实在太多,也全都是混淆,若是想用 python 来实现的话也不是不可能,就是成本太大了,须要的时间太多了,咱们还不如直接使用 python 的 execjs 来执行 JavaScript 代码直接得到就能够了,这个简单方便。
(咱们除了使用 execjs 来执行,还可使用 selenium 运行这个html 文件也是能够的,可是我并不想用 selenium 这个工具,仍是喜欢折腾,因此忽略了,想用的能够试试。)
可是这里又会有一个问题,咱们用浏览器打开的是为它提供了一个浏览器的运行环境,咱们在 python 使用的 execjs 提供的是 node 环境,两个环境的不同,就会产生不一样的效果,下面咱们能够选择使用 webstorm 编辑器来提供 nodejs 环境来进行尝试如下。
5. 在 node 环境调试加密代码
你能够拿上面的 JavaScript 代码在 webstorm 运行,你就会看到
TypeError: __g._encrypt is not a function
因此咱们须要调试,须要把那些在浏览器上只有的对象,好比 window、navigator 之类的对象给弄掉,从而在 node 上用不用的代码代替相同的效果便可。
要调试咱们先要找到代码运行的开端,能够很容易找到
能够看到,这里它会先去判断有没有 window 这个对象来判断是否是在浏览器上面运行的,因此咱们能够直接把它修改为 true 或者其余****表示成 true 的值均可以
再次运行,能够看到这个错误
ReferenceError: atob is not defined
这个 atob 是将 base64 加密的字符串给解密,在 node 环境下是没有这个方法的,咱们须要使用 Buffer.toString()替代便可。
运行以后,仍是报这个错误
TypeError: __g._encrypt is not a function
注意:这个是大坑,估计通常人每一个一两天还搞不定,这个是由于上面的解密的,可是上面的并不同,你能够在上面的两个函数加断点,分别在浏览器和 node 环境下运行,能够看到解密的数据是不同的,是由于在浏览器上的 base64 加密的是 binary 编码,解密以后也就一样须要使用 binary 编码,这个是我在知乎的资源文件上搜索 atob 这个方法,而后慢慢查找看到的,当时也差很少心态崩了,还好坚持下来了。而我在 node 环境下解密以后使用了默认的编码,因此解密的数据出错了。当咱们加上 binary 编码以后,再运行
这时,错误再也不是上面那个了,变成了另外一个,证实解密正确了,再来看看下面这个错误
execption at 11: ReferenceError: window is not defined
原来是 window 对象惹的祸,这个时候就须要咱们伪造 window 对象了,至于怎样伪造呢,咱们能够调试出错的地方,看看它使用了什么方法,就直接使用适合 node 运行的相同效果的代码代替就能够了,通过屡次调试,须要咱们伪造 window 和 navigator 这两个对象,下面就是伪造以后的代码
这个时候再运行看看。
能够看到成功了,上面的红色字是一个提示,关于 Buffer 的,这个咱们忽略就行,接下来就可使用 python 环境进行测试了。
果真,都出来了,哈哈,注意须要先安装 PyExecJS 库,自行安装,而后在测试的时候记得导入 execjs 便可。如今这个 fromdata 算是大功告成了,接下来就是登录验证下咱们搞得这个加密对不对了。
6. 模拟登录知乎
这个知乎的登录也是坑满满,我也给踩了几个,这个就直接说坑吧,其余的就很少说了。
我只是用手机号来登录的,也能够用邮箱登录,过程都差很少的。
1. 请求登录的网址的请求头须要带上这几个
不带 content-type 的话,会给你返回这个错误
Missing argument grant_type
不带 x-zse-83 的话,会给你返回这个错误
请求参数异常,请升级客户端后重试
至于 agent-user 那就更不须要说了。
2. 请求顺序
知乎这个登录是首先请求验证码地址,看须要不须要填写验证码,若是须要填就再请求一次,并且还须要再再请求一次查看是否输入验证码正确,不正确就重复上面步骤,当不须要填写验证码的时候就能够直接请求登录网址了。
还有上面的三次请求的验证码地址的请求方法都是不同的,哪一种方法自行调试便可。
3. 验证验证码
在验证验证码的时候请求头的 content-type 不要填写 值为 multipart/form-data,若是填了请求验证码的时候会给你返回这个错误:
{"error":{"message":"Missing argument input_text","code":400}}
它的意思是说没有带上验证码验证,当咱们去掉的这个字段的时候,就能够验证了。
验证验证码的时候请求头只须要有一个** user-agent **就能够了
4. 请求的全部阶段带上 cookie
知乎这个有个 cookie 值是验证码票据,是从第一次请求验证码地址来的,就是下面这个
若是不带 cookie请求或者请求顺序不同都有可能给你返回这个错误。
{"error":{"message":"缺乏验证码票据","code":120002,"name":"ERR_CAPSION_TICKET_NOT_FOUND"}}
5.
你还想要?没有了,坑暂时只有这么多,最后给大家看下登录成功的结果
7. 写在最后
这个登录折腾了差很少一周了,实际来讲多是三周,由于从刚开始看不懂 js 代码,就跑去学了两周 js,如今总得来讲 js 也能够说上手了,之后或许也会使用 nodejs 搞点爬虫,挺好玩的。
至于代码,暂时不公布了,若是你一步一步按照我方法来弄的话估计也能够,前提的有 js 基础最好,之后会公布的,等我再完善先,由于还须要干别的东西。若是有问题也能够找我,加我微信 june--98 拉你进群讨论便可。
折腾这个,掉了很多头发,但据说分享点赞是生发之道,因此大家懂的!