QQ模擬登入實現後篇
0x00 概述
本來是和上篇文章一起發的,後來出去,就擱置了。
比較高興有人參與討論和吐(B)槽(4),其實本身也沒啥高大上的技術,只是自己在對以前工具做review和重構的時候發現,這些東西很少人在討論分享,所以也就放出來,算是拋磚引玉。
今天分享兩個東西。
- QQ模擬登入實現之愚公移山(流程自實現)
- QQ模擬登陸實現之草船借箭(客戶端快速登入實現)
當然,乾貨也就意味著乏味,如果大家不想看文章的可以直接看程式碼。
第一個分享是對我上一篇文章的補充,QQ模擬登入實現之四兩撥千斤(基於V8引擎)
自己參考TX JS程式碼實現的加密流程,因為個人能力有限,所以TX的tea演算法是直接引用的hoxide 2005基於python的實現。
第二個分享其實是主要是利用QQ客戶端實現快速登入,快速登入對環境有一定的依賴,但是也有很多好處,我們不用處理密碼;當然,這種登入方式的使用場景比較有限,目前主要在爬蟲和掃描器的場景。
0x01 QQ模擬登入實現之愚公移山(流程演算法實現)
在上一篇文章:QQ模擬登入實現之四兩撥千斤(基於V8引擎)
中我們分享了QQ帳號密碼登入的流程和基於JS引擎實現的密碼加密方式,我們用一種簡單實用的方式實現了“能用”。
但是對於一個做安全愛好者,有時候我們需要深入一些,整個加密的流程和演算法,我們是不是自己可以實現一套?所以,本文的重點,是對TX密碼處理流程的分析。
密碼處理流程
總體說明
瞭解了登入流程,我們在要分析和實現模擬登入需要考慮一個問題,密碼是如何處理的?
要了解密碼是如何處理的,我們先要了解以下3種演算法:MD5,RSA,TEA。其中MD5是hash演算法,比較常用;RSA是一種非對稱加密演算法,大家也比較瞭解。這裡需要說明一下TEA演算法。
TEA演算法Tiny Encryption Algorithm,是一種分組加密演算法,實現比較簡單。TEA演算法使用64位的明文分組和128位的金鑰,需要進行 64 輪迭代。
不過TX_TEA演算法對傳統的TEA演算法進行了一些修改,具體的原理可以參考登入的JS。這裡簡單說明下:TX只使用了16輪迭代;TX_TEA加密的是資料流,並且採用的是反饋隨機交織填充方式。
加密流程
加密總流程圖
基本上看懂這個流程圖,就明白QQ密碼的加密流程了。
淺藍色的是來源資料,綠色是一些密碼的處理方法(加密、HASH、替換)。
來源資料:
密碼:password
salt:salt,來源於check介面的返回
verifycode: 來源於check介面的返回
rsaKey在js原始碼裡面可以獲取
資料說明:
- rsaData: rsa(md5(pwd), rsaKey)
- hex_verifycode: verifycode 的16進位制
最後進行tea演算法tea(v, k)
- v是 (rsaDataLen + rsaData + salt + verifycodeLen + hex_verifycode) 的byte陣列
- k是 md5(md5(pwd) + salt) 的byte陣列
結果進行base64編碼
Replace是做一個簡單的替換,對以下3個字元進行替換
/ -> -
+ -> *
= -> _
最後得出加密的密碼,長度為216的字串,形式參考如下:
#!bash
37Hro2-AgR4d8ZkU1L-6FqYhTUdhywhLlD2WihfVZGqZmz5R1RlwBsYPNowY0ZHJxcISmwpW0e7ppcoEDTGYyM5*6ZPJNUnZnb4h4Ke*qIBnFlTkiYFUhUwvXgOEvfIDTgCZIWsiFT6EauXujkB2i5yNFobx9aN5vw2xFyE1E2VoF*LV952q0mQO-HiooQZfMocl13kxFgxtVQaSRpm7Rg__
參考程式碼:
#!python
def tx_pwd_encode(self, pwd, salt, verifycode):
"""
js:getEncryption(t, e, i, n)
t=pwd, e=salt 二進位制形式, i=verifycode, n:default undefined
# """
salt = salt.replace(r'\x', '')
e = self.fromhex(salt)
md5_pwd = o = self.tx_md5(pwd)
r = hashlib.md5(pwd).digest()
p = self.tx_md5( r + e )
a = rsa.encrypt(r, self.rsaKey)
rsaData = a = binascii.b2a_hex(a)
# rsa length
s = self.hexToString( len(a)/2 )
s = s.zfill(4)
# verifycode先轉換為大寫,然後轉換為bytes
verifycodeLen = hex(len(verifycode)).replace(r"0x","").zfill(4)
l = binascii.b2a_hex( verifycode.upper() )
# verifycode length
c = self.hexToString( len(l)/2 )
c = c.zfill(4)
# TEA: KEY:p, s+a+ TEA.strToBytes(e) + c +l
new_pwd = s + a + salt + c + l
saltpwd = base64.b64encode(
tea.encrypt( self.fromhex(new_pwd), self.fromhex(p) )
).decode().replace('/', '-').replace('+', '*').replace("=", "_")
程式碼傳送門:
https://github.com/LeoHuang2015/qqloginjs/blob/master/autologin_account.py
0x02 QQ模擬登陸實現之草船借箭(客戶端快速登入實現)
我們在對QQ進行爬取和掃描的時候,很多時候需要考慮到登入的情況,如果使用使用者名稱密碼的方式,可能因為一些風控規則,當我們多次登陸時就要求圖片驗證碼,而使用快速登入就能很好的規避這種情況。
流程梳理
客戶端快速登入方式是使用者在PC端已經登入了QQ客戶端軟體,如果使用者再開啟Web頁面進行登陸,不用再輸入使用者名稱和密碼,只需要選擇已經登入的帳號,點選確認登入即可。
快速登入的本質上是使用clientkey置換token。
QQ客戶端登陸後會生成一個長224的clientkey認證字串,每次登陸都會變化,參考如下:
#!bash
000156DCEB4E0068663F53B8B402784291BB6E74C482BFB6367FF48FB970443E9B9682359E8F1F92D5A814B097D12D938B96B30742DDE5CDA8E453EB7CD31A5121416637D945615C661285F5306884D959184AB1E4F7CFA83BC9FAF069C1E5878320ECF79EF8751320763492752A1433
早期快速登入的實現方式是各個瀏覽器使用外掛,如IE的 ActiveX控制元件支援的,firefox是外掛,透過外掛植入clientkey。
後續支援非外掛的形式,每次動態的訪問QQ客戶端繫結的本地server(localhost.ptlogin2.qq.com)獲取clientkey,然後再用clientkey去置換token。
整體流程
客戶端快速登入主要分為兩種情況:
一種是外掛模式,直接使用clientkey置換token登陸;
另外一種是費外掛模式,或者clientkey出現一些異常情況,透過請求server把clientkey設定到cookie,然後再置換token登陸。
流程分析
clientkey存在且正常/外掛模式
1.元件載入&獲取使用者頭像資訊
同帳號和密碼登陸,只是這裡獲取已經登陸QQ客戶端的使用者頭像和暱稱。
獲取登陸資訊,使用者
http://ptlogin2.qq.com/getface
返回:帳號、頭像地址(有多個客戶端登陸的帳號,請求多個)
2.登陸
使用者點選登陸,實際上是一個clientkey置換token的過程。
請求會帶上clientkey進行認證
http://ptlogin2.qq.com/jump
如果client不正確,則會登陸失敗,後續登陸不會信任原來的clientkey,會走clientkey不存在/異常的流程。
clientkey不存或者異常/沒有安裝外掛
1.元件載入&獲取使用者資訊&獲取使用者頭像資訊
由於clientkey這裡會多一步獲取使用者資訊的流程
參考url:
#!bash
http://localhost.ptlogin2.qq.com:4300/pt_get_uins
?callback=ptui_getuins_CB
&r=0.5314265366275367
&pt_local_tk=0.3291951622654449
返回,賬號資訊,客戶端型別,暱稱等資訊
PS:這裡如果獲取不到會進行重試,一共5次,比如http的埠依次是4300,4302,4304,4306,4308。
然後再獲取使用者頭像資訊(同上)。
2.登陸
獲取clientkey
參考URL:
#!bash
http://localhost.ptlogin2.qq.com:4300/pt_get_st
?clientuin=1802014971
&callback=ptui_getst_CB
&r=0.11057236711379814
&pt_local_tk=0.3291951622654449
返回:設定clientkey到cookie,返回回撥方法
#!js
var var_sso_get_st_uin={uin:"1802014971"};ptui_getst_CB(var_sso_get_st_uin);
然後進行登陸置換
http://ptlogin2.qq.com/jump
返回:設定cookie
#!js
ptui_qlogin_CB('0', 'http://www.qq.com/qq2012/loginSuccess.htm', '');
設定完cookie後,再請求ptlogin2.qq.com域的如下url來完成對ptlogin2.qq.com域和qq.com域的認證cookie的設定,同時刪除clientuin和clientkey這兩個cookie值。
模擬實現
我們需要模擬實現的快速登入,需要走非外掛模式的流程,流程本身比較簡單,也沒有比較複雜的演算法,如下:
- 獲取簽名
- 獲取客戶端QQ號碼
- 使用者名稱和環境檢測
- 獲取clientkey
- 置換token
這裡有兩個安全點需要注意:
- Token校驗:請求的
pt_local_tk
會和cookie中的pt_local_tk
校驗; - Referrer驗證:referer限制了QQ域。
參考程式碼:
#!python
def get_client_uins(self):
'''
get client unis info
need: token check & referer check
'''
tk = "%s%s" %(random.random(), random.randint(1000, 10000) )
self.session.cookies['pt_local_token'] = tk
self.session.headers.update({'Referer':'http://ui.ptlogin2.qq.com/'})
具體實現參考程式碼:
https://github.com/LeoHuang2015/qqloginjs/blob/master/autologin_quick.py
相關文章
- 【Java】——模擬登入實現2020-12-06Java
- 實戰模擬│單點登入 SSO 的實現2022-07-08
- 用python實現模擬登入人人網2016-04-11Python
- 實戰:Mailivery 模擬登入2024-11-13AI
- QQ模擬登入實現之四兩撥千斤(基於V8引擎)2020-08-19
- 實戰模擬│JWT 登入認證2022-07-04JWT
- QQ 快速登入協議分析與實現2019-09-14協議
- Java實現QQ第三方登入2020-02-01Java
- Python自動登入QQ的實現示例2020-11-23Python
- Python-模擬登入2018-11-30Python
- windows 安裝 企業QQ後,個人qq無法登入2018-11-01Windows
- 用不同的庫實現模擬登陸知乎!2020-10-22
- 利用Python模擬GitHub登入2019-07-14PythonGithub
- python使用Cookie模擬登入2017-11-08PythonCookie
- C#模擬登入總結2010-05-07C#
- 模擬登入之web監控2024-06-11Web
- 用 hyperf websocket 實現,類似 qq 單機登入功能2019-09-23Web
- laravel實現第三方qq一鍵登入2018-07-27Laravel
- 如何在自己的網站上實現QQ授權登入?2015-10-23網站
- Python爬蟲實戰之(五)| 模擬登入wechat2018-04-10Python爬蟲
- 【網頁登入】QQ 登入、微信登入、微博登入、GitHub 登入2019-10-29網頁Github
- 使用 mock 模擬登入介面資料2021-08-26Mock
- golang 模擬瀏覽器登入操作2018-09-15Golang瀏覽器
- python模擬登入網易郵箱2015-09-28Python
- Python培訓分享:python如何用cookie實現自動模擬登入?2021-11-08PythonCookie
- C#三種模擬自動登入和提交POST資訊的實現方法2010-03-18C#
- 簡單實現第三方qq登入和分享2018-12-07
- Flutter入門篇(三)— 如何實現登入動畫效果2019-03-17Flutter動畫
- 讓我大吃一塹的前後分離 web 站模擬登入2019-03-04Web
- Python+Selenium+phantomjs實現網頁模擬登入和截圖2019-12-11PythonJS網頁
- Python爬蟲之模擬知乎登入2017-03-30Python爬蟲
- Python 爬蟲(七)-- Scrapy 模擬登入2017-08-31Python爬蟲
- 爬蟲模擬登入—OAUTH的詳解2018-05-10爬蟲OAuth
- SQL Server模擬別的賬戶登入2011-07-15SQLServer
- [API 寫法] QQ 登入、微信登入、Facebook、google、蘋果登入2020-02-06APIGo蘋果
- 爬蟲實戰(二):Selenium 模擬登入並爬取資訊2018-07-15爬蟲
- Python爬蟲實戰之(四)| 模擬登入京東商城2018-04-11Python爬蟲
- promise的模擬實現2018-03-17Promise