圖1
接下來,我將詳細解釋每個過程。
第一步:預登錄。
現(xiàn)在微博、空等大型網(wǎng)站基本都是輸入用戶名后再做編碼或者加密。這里在用戶名輸入框輸入我的賬號,可以看到服務器會通過抓包工具返回一個字符串:
圖2
這一步是預登錄過程。學生可以自己嘗試。我們需要在登錄時使用servertime、nonce、pubkey等字段。當然這不是我自己的猜測,接下來的步驟會說明。
還有一點是預登錄的網(wǎng)址:
http://login.sina.com.cn/sso/prelogin.php?詞條=微博& ampcallback = Sinasocontroller . PreLoginCallback & amp;su = & amprsakt = mod & ampcheckpin = 1 & ampclient = SSO log in . js(v 1 . 4 . 18)amp;_=1461819359582
這里su的值是你自己用戶名的編碼值。但也許你會問我怎么知道的。我以后再說。實際測量后,如果不在這里給su傳遞參數(shù),其實是可以的。為了最逼真地模擬用戶登錄,我們最好帶上它的價值。
請看圖1中http://i.sso.sina.com.cn/js/ssologin.js的第一個js請求。學生可以點進去看看。這是一系列的加密文件,比如上面提到的加密用戶名和密碼。如果有同學非要問我怎么找到這個加密文件,我只能說:反復搶包。在瀏覽器中輸入weibo.com之后,找到請求路徑的js文件,然后用代碼格式化工具打開它,一個一個地查找,并在代碼中搜索關鍵字。例如,我們可以在這里搜索“現(xiàn)時”、“服務器時間”等。,我們就能找到加密文件。
打開加密文件,我們可以看到加密用戶名的代碼。在加密的js文件中搜索“username”,我們可以看到有一行代碼:
_ username = sinaSSOEncoder..encode(URL encode(username));_現(xiàn)在可以直接找到編碼方法(代碼太多就不貼了),然后就可以找到對應的方法了。為了驗證我們的猜測,我們可以復制webstorm中的encode函數(shù),用自己的用戶名運行,返回的結果就是su的值,這個值也將在后面的帖子提交中用到。如果你有一定的加密經(jīng)驗,可能一眼就看出這是代碼。python中有一個模塊可以做到這一點。讓我們回到圖1,http://login.sina.com.cn/sso/login.php?客戶端=ssologin.js(v1.4.18)這個地址是數(shù)據(jù)后提交的地址,下面是我自己提交的數(shù)據(jù):
圖三
這里我們需要自己構造su(加密用戶名)、sp(加密密碼)、servertime、nonce、rsakv等數(shù)據(jù),其他數(shù)據(jù)不需要改動。有同學問我為什么其他數(shù)據(jù)不用改??梢远啻蔚卿洸榭锤牡闹?,那么那些值就是需要構造的值,其他的值可以直接使用。這里的su,su,servertime,nonce,rsakv rsakv都已經(jīng)得到,所以現(xiàn)在需要的只是sp值。我們還是按照原來的方法在js文件中尋找“sp”,可以找到代碼requests.sp=password,所以只需要看看密碼是如何構造的。通過搜索,您可以看到密鑰加密代碼:
password = RSa key . encrypt([me . server time,me.nonce]。加入(" t") "n "密碼)
這段代碼就是加密密碼的代碼。有經(jīng)驗的同學會知道用的是rsa加密,python中有相應的RSA加密庫。但是我們假設沒有人能夠看到或者知道python中有第三方庫rsa。這時,我想向你介紹一下我的一些經(jīng)歷。我已經(jīng)知道有三種模擬登錄方案:a)最簡單高效的,直接將js源代碼轉(zhuǎn)換成相應的python代碼,模擬加密過程進行加密;b)使用selenium phantomjs/firefox的方案直接模擬人工操作,填寫表單,提交數(shù)據(jù)進行模擬登錄,最簡單,效率稍低。如果學生對這種簡單暴力的方式感興趣,可以在我的github上查看源代碼c),通過pyv 8/pyxecjs渲染js代碼,這是本文的主要方式。第一種方式,微博如果調(diào)整登錄加密算法,加密碼一定要改。第二種方式和第三種方式?jīng)]有這個問題。
因為使用Python3,不支持PyV8,所以選擇了Pyexecjs,和Python 3類似,也可以直接執(zhí)行js代碼。我對Java代碼也不是很熟悉,所以直接定義了一個函數(shù)來處理加密密碼,并沒有過多修改其加密源代碼:
函數(shù)get_pass(mypass,nonce,servertime,rsakey){
varRSAKey = newsinaSSOEncoder。RSakey();
RSAKey.setPublic(rsakey," 10001 ");
password = RSa KeY . encrypt([server time,nonce]。join("t") "n" alt="登陸新浪微博 超詳細的Python實現(xiàn)新浪微博模擬登陸">