python-微博模拟登录

相比于上一篇知乎模拟登录,本篇的微博模拟登录则更为复杂一些。

打开firefox的开发者模式,清楚相关网站的cookies,以防因为某些重要文件已经被缓存,而观察不到相应的HTTP交互。进行微博登录,观察HTTP交互状况,以下将对过程进行分析:

第一步:预登录
现在很多网站都会进行预登录,对输入的用户名进行编码或者加密处理。
这里写图片描述
这里写图片描述
该请求对应的响应为:
sinaSSOController.preloginCallBack({“retcode”:0,”servertime”:1504752958,”pcid”:”gz-09567206091c76921bb8a6a83f424755d99a”,”nonce”:”1468SE”,”pubkey”:”EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443”,”rsakv”:”1330428213”,”is_openlock”:0,”showpin”:0,”exectime”:12})

通过观察参数,猜测su是处理后的用户名,为一长串的数字,极有可能是时间戳。经过多次的模拟登录查看,发现只有 参数会变化。至于响应放回的数据,目前也不知道有什么作用,等接下来再进行分析。

第二步 登录:
按顺序查看HTPP交互,我们发现一个HTTP请求极有可能是登录请求:
这里写图片描述
这里写图片描述

通过其的请求网址以及post这么多数据,登录请求必是它无疑了。通过分析该请求的参数,发现之前预登录返回的servertime,nonce,rsakv等都在里面。然后我们需要多次模拟该请求,从而找出参数中哪些参数是不变的,哪些参数是变化的。

最终得出的结论:sp,su,servertime,nonce,raskv是变化的,而servertime,nonce,raskv等可以通过预登录的响应中找到,所以关键就是求出sp,su.

另外可以通过参数中得到一个重要信息,那就是该请求调用了ssologin.js文件,可以说该文件起到了至关重要的作用。

查看请求ssologin.js的http请求:
这里写图片描述

通过点击https://i.sso.sina.com.cn/js/ssologin.js ,我们就可以查看该文件的内容,该文件就是进行加密用户名和密码等一系列的加密文件。

在ssologin.js中查找username,通过对匹配的代码进行分析,发现该行:
username = sinaSSOEncoder.base64.encode(urlencode(username));
因此猜测微博对用户名的处理就是先进url编码然后在进行base64编码。通过python编码进行验证,确实是这样的。

接下来在该文件中查找password,通过对匹配的代码进行分析,发现该行:
password = RSAKey.encrypt([me.servertime, me.nonce].join(“\t”) + “\n” + password)
猜测该代码就是对password进行加密,rsa是目前应用最广的公钥密码体制,基本上主流语言都有rsa的实现类库。公钥密码体制中十分重要的就是公钥和私钥,我们需要公钥来进行加密。那么公钥又是多少呢?

在该代码周围发现另外的代码:
RSAKey.setPublic(me.rsaPubkey, “10001”);
该代码应该就是设置公钥,还记得预登录时返回的那个pubkey,那个应该就是rsaPubkey。然后即使知道这些所有的参数,相同的处理过程,也无法得到一样的结果,因为rsa为了增加破译难度,在其实现中加入了随机因子,所以只能通过判断登录是否成功来验证。rsa的诞生可以说是对密码学的一次颠覆,有兴趣的朋友可以读读相关论文。

在模拟实现用户名和密码加密时有两个方案:1.使用python实现其关键代码 2.通过PyexecJS来直接执行js代码

第三步 重定向:
一般来说执行到第二步就完成了,返回首页的HTML代码,但微博有点与众不同,它进行了一系列重定向才跳转到首页。

我们来看看成功发生登录请求后,相应的http响应:
这里写图片描述

我们可以看到是一段html代码,其中location.replace函数进行跳转。然后我们查找请求地址为该参数的请求,其响应如下:
这里写图片描述

我们发现其响应中的html代码依然会自动进行跳转,在继续查找该地址的http请求,结果如下:
这里写图片描述

其状态码为302,进行了重定向,观察其重定向的http请求:
这里写图片描述
其响应为:
parent.sinaSSOController.feedBackUrlCallBack({“result”:true,”userinfo”:{“uniqueid”:”1797442073”,”userid”:null,”displayname”:null,”userdomain”:”?wvr=5&lf=reg”}});

暂时还不知道其具体有什么用,我们继续按顺序往下查看http请求,发现http请求如下:
这里写图片描述

该http请求的参数正好就是前面的userdomain,然后该http请求的状态码也是302,所以我查看其重定向的http请求:
这里写图片描述

该http请求的响应就是登录进去后的页面的html代码,到此就微博模拟登录就成功了。

关于登录中可能涉及到的验证码处理方案有三个:1.就是花钱,现在有很多打码平台,比如云打码,它们都提供了相应的api来集成它们的功能 2.自己使用深度学习方法训练分类器,比如卷积神经网络 3.保存验证码,然后展示给用户,要求用户自己手动输入。

本篇的内容是在http://www.jianshu.com/p/816594c83c74 基础上得出的。其实代码实现并不难,但是登录协议的分析才是核心。

本篇的实现代码:https://github.com/EdwardLee0331/weiboLogin