1.预登陆打开微博首页进行登陆,打开Charles抓包然后看请求信息,预登陆的链接需要一下以下几个参数
https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1529027960561
其中我们需要获取su的参数
2.https://login.sina.com.cn 所以这里面肯定有一些需要登陆用到的东西,我们打开这个sso文件夹 看到login.php?开头的页面,查看其中的请求参数,看到了这么一大堆。su(加密后的用户名),sp(加密后的密码),其他的参数下面依次分析。
然后继续分析请求,一般post里的请求参数都是通过js里的ajax的post提交过来的,所以我们先找找有没有js文件之类的含有这几个参数。
3.找到的js:http://i.sso.sina.com.cn/js/ssologin.js
打开然后格式化,然后尝试搜索上面的post参数中的一个,一般搜出现次数可能比较低的次,如果你搜su估计会搜出一大堆su开头的词看到。
上图的320行提示我们username是加密了的,同时观察325行可以知道su实际就是username的加密
username = sinaSSOEncoder.base64.encode(urlencode(username));
su的加密方式破解:
(1).sinaSSOEncoder,搜索发现 var sinaSSOEncoder = sinaSSOEncoder || {};
如果对象存在使用对象如果不存就是初始化为空对象。所以我们知道了,sinaSSOEncoder是一个对象。base64就是相应的属性了 我们继续搜
搜到如下代码段得到如下代码 所以我们知道base64对象属性encode的值为那个函数。(js资料:https://blog.csdn.net/aa294194253/article/details/42972959)
于是我们得到了加密算法base64
this.base64 = { encode: function(n) { n = "" + n; if (n == "") { return "" } var l = ""; var u, s, q = ""; var t, r, p, o = ""; var m = 0; do { u = n.charCodeAt(m++); s = n.charCodeAt(m++); q = n.charCodeAt(m++); t = u >> 2; r = ((u & 3) << 4) | (s >> 4); p = ((s & 15) << 2) | (q >> 6); o = q & 63; if (isNaN(s)) { p = o = 64 } else { if (isNaN(q)) { o = 64 } } l = l + this._keys.charAt(t) + this._keys.charAt(r) + this._keys.charAt(p) + this._keys.charAt(o); u = s = q = ""; t = r = p = o = "" } while ( m < n . length ); return l }
(2).括号里的urlencode(参考资料:http://www.w3school.com.cn/jsref/jsref_encodeURIComponent.asp)
var urlencode = function(str) { return encodeURIComponent(str) };
以上的过程我们用python实现就是先对url进行编码,然后再进行base64的编码,同时
def get_encodename(name): username_quote = quote_plus(str(name)) username_base64 = base64.b64encode(username_quote.encode("utf-8"))#b64encode需要接受字节类型所以编码了 return username_base64.decode("utf-8")#如果不加decode解码则返回的是字节类型。
到这里su的参数就告一段段落了。
我们请求第一步获取的链接
https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1529027960561
得到如下内容,由此我们得到几个重要的参数nonce,raskv,
sinaSSOController.preloginCallBack({ "retcode": 0, "servertime": 1529027940, "pcid": "tc-f913b30dd980d2bd36f2bf2ddd56eb406f62", "nonce": "OM523B", "pubkey": "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443", "rsakv": "1330428213", "is_openlock": 0, "lm": 1, "smsurl": "https:\/\/login.sina.com.cn\/sso\/msglogin?entry=weibo&mobile=18810668312&s=5a689123ea56abf7e2d399ab4f878dc7", "showpin": 0, "exectime": 8 })
3.接着搜sp得到如下代码,之后搜password的到一个RSA加密算法的逻辑
var RSAKey = new sinaSSOEncoder.RSAKey(); RSAKey.setPublic(me.rsaPubkey, "10001"); password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
request.sp = password;
以下用python实现
def get_password(password, servertime, nonce, pubkey): rsa_publickey = int(pubkey, 16) key = rsa.PublicKey(rsa_publickey, 65537) #创建公钥 message = str(servertime) + '\t' + str(nonce) + '\n' + str(password) #创建公钥 message = message.encode("utf-8") passwd = rsa.encrypt(message, key) #加密 passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。 return passwd