本周又和大家見面了规肴,沒什么特殊情況捶闸,一般是一周一篇原創(chuàng)。發(fā)布的時間基本上是在周末拖刃,平時還是比較忙碌的删壮。最近在開發(fā)自己的博客,過段時間可以和大家分享開發(fā)博客中的技術(shù)點兑牡。如果大家想及時的和我交流的話央碟,可以關(guān)注文章最后的微信公眾號,這樣我可以比較及時的知道大家的想法均函。(我的新書《Python爬蟲開發(fā)與項目實戰(zhàn)》發(fā)布了亿虽,大家在這里可以看到樣章)
好了,廢話不多說苞也,咱們進入今天的主題洛勉,講解一下前段時間做的百度登錄加密協(xié)議分析,由于寫的比較詳細如迟,篇幅有點多收毫,所以就分為上下兩篇來寫攻走。由于百度登錄使用的是同一套加密規(guī)則,所以這次就以百度云盤的登錄為例進行分析此再。
<h1>第一部分:</h1>
首先打開firebug昔搂,訪問http://yun.baidu.com/,監(jiān)聽網(wǎng)絡(luò)數(shù)據(jù)输拇。
流程:
1.輸入賬號和密碼摘符,點擊登錄。
2.點擊登錄策吠。(第一次post,這時候會出現(xiàn)驗證碼)
3.會出現(xiàn)驗證碼逛裤,輸入驗證碼,
4.最后點擊登錄成功上線奴曙。(第二次post登錄成功)
根據(jù)以往的分析經(jīng)驗,一般需要進行兩次登錄草讶,來比較post請求出去的數(shù)據(jù)洽糟,哪些字段是不變的,哪些字段是動態(tài)改變的堕战。同樣上述的流程坤溃,這次也會重復一次。將兩次登錄過程中產(chǎn)生的post請求保存下來嘱丢。
在一次成功的登錄過程中薪介,我們需要點擊兩次登錄按鈕,也就出現(xiàn)了兩次post請求越驻。
咱們先關(guān)注最后一次post的請求內(nèi)容汁政。
這個時候從賬號登出,清除cookie信息缀旁,再進行一次登錄過程记劈,再把post出去的數(shù)據(jù),記錄下來,進行比較哪些是變化的并巍。
通過兩次的比較目木,我們可以發(fā)現(xiàn):
**apiver=v3**
callback=parent.bd__pcbs__yqrows
**charset=utf-8**
codestring=jxGa206f4ef6540e2a5023014affd01abcc160fde066101382d
**countrycode=**
**crypttype=12**
**detect=1**
**foreignusername=**
gid=58DDBCC-672F-423D-9A02-688ACB9EB252
**idc=**
**isPhone=**
**logLoginType=pc_loginBasic**
**loginmerge=true**
**logintype=basicLogin**
**mem_pass=on**
password
**quick_user=0**
rsakey=kvcQRN4WQS1varzZxXKnebLGKgZD5UcV
**safeflg=0**
**staticpage=http://yun.baidu.com/res/static/thirdparty/pass_v3_jump.html**
**subpro=netdisk_web**
token=69a056f475fc955dc16215ab66a985af
**tpl=netdisk**
tt=1469844379327
**u=http://yun.baidu.com/**
username
verifycode=1112
其中標有的字段*都是不變化的,其他都是變化的懊渡。
接著看一下變化的字段:
callback 不清楚是什么
codestring 不清楚是什么
gid 一個生成的ID號
password 加密后的密碼
ppui_logintime 時間刽射,不知道有沒有用
rsakey RSA加密的密鑰(可以推斷出密碼肯定是經(jīng)過了RSA加密)
token 訪問令牌
**tt 時間戳**
**verifycode 驗證碼**
上面標為*的部分,都是可以簡單獲取的剃执,所以先不用考慮誓禁。
<h1>第二部分:</h1>
<h4>(1) 采取倒序的分析方式,上面說了一下第二次post的值肾档,接著咱們分析一下现横,第一次post的數(shù)據(jù)內(nèi)容。 </h4>
通過兩次post比較戒祠,可以發(fā)現(xiàn)一下字段的變化:
callback 第一次post已經(jīng)產(chǎn)生骇两,第二次post內(nèi)容發(fā)生變化
codestring 第一次post時沒有數(shù)據(jù),第二次post產(chǎn)生數(shù)據(jù)
gid 第一次post已經(jīng)產(chǎn)生,第二次post內(nèi)容沒有發(fā)生變化
password 第一次post已經(jīng)產(chǎn)生姜盈,第二次post內(nèi)容發(fā)生變化
ppui_logintime 第一次post已經(jīng)產(chǎn)生低千,第二次post內(nèi)容發(fā)生變化
rsakey 第一次post已經(jīng)產(chǎn)生,第二次post內(nèi)容沒有發(fā)生變化
token 第一次post已經(jīng)產(chǎn)生馏颂,第二次post內(nèi)容沒有發(fā)生變化
從上面可以看到出現(xiàn)明顯變化的是codestring ,從無到有示血。
可以基本上確定 codestring 是在第一次post之后產(chǎn)生的,所以codestring 這個字段應(yīng)該是在第一次post之后的響應(yīng)中找到救拉。
果然不出所料:
codestring 這個字段的獲取位置已經(jīng)確定难审。
<h4>(2) 接下來 分析第一次post已經(jīng)產(chǎn)生,第二次post內(nèi)容沒有發(fā)生變化的字段 </h4>
gid
rsakey
token
根據(jù)網(wǎng)絡(luò)響應(yīng)的順序亿絮,從下到上告喊,看看能不能發(fā)現(xiàn)一些敏感命名的鏈接(這是之前的經(jīng)驗)
從第一次post的往上看,一個敏感的鏈接就出現(xiàn)了派昧。
https://passport.baidu.com/v2/getpublickey?token=69a056f475fc955dc16215ab66a985af&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1469844359188&gid=58DDBCC-672F-423D-9A02-688ACB9EB252&callback=bd__cbs__rn85cf
通過查看響應(yīng)我們找到rsakey黔姜,雖然在響應(yīng)中變成了key,可是值是一樣的。
通過之前的信息蒂萎,我們知道密碼是通過RSA加密的秆吵,所以響應(yīng)中的publickey可能是公鑰,所以這個要重點注意五慈。
咱們還可以發(fā)現(xiàn)callback 字段纳寂,參數(shù)中出現(xiàn)callback字段,之后響應(yīng)中也出現(xiàn) 了 callback字段的值將響應(yīng)包裹取來泻拦,由此可以推斷callback字段可能只是進行標識作用烈疚。不參與實際的參數(shù)校驗。
通過這個get鏈接的參數(shù)聪轿,我們可以得出結(jié)論:
gid和token可以得到rsakey參數(shù):
gid token ------->>>>>rsakey
<h4>分析 gid和token字段 </h4>
為了加快速度爷肝,咱們直接在firebug的搜索框中輸入token:
搜索兩三次就發(fā)現(xiàn)了token的出處。
https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1469844296412&class=login&gid=58DDBCC-672F-423D-9A02-688ACB9EB252&logintype=basicLogin&callback=bd__cbs__cmkxjj
通過get請求的參數(shù)可以得出這樣的結(jié)論:
通過gid可以得出來Token
gid----------->>>>>>>>token
<h4>最后咱們分析一下gid: </h4>
依然是搜索gid ,搜索幾次就在這個腳本中發(fā)現(xiàn)了gid的存在:
http://passport.bdimg.com/passApi/js/login_tangram_a829ef5.js
格式化腳本之后陆错,咱們看一下這個gid是怎么產(chǎn)生的
通過gid:e.guideRandom ,我們可以知道gid是由guideRandom這個函數(shù)產(chǎn)生的灯抛,接著在腳本中搜索這個函數(shù);
最后找個了這個函數(shù)的原型,但是通過代碼可以看到音瓷,這個是隨機生成的一個字符串对嚼,這就好辦了(百度。绳慎。纵竖。其實當時我是無語的)漠烧。
gid = this.guideRandom = function () {
return 'xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (e) {
var t = 16 * Math.random() | 0,
n = 'x' == e ? t : 3 & t | 8;
return n.toString(16)
}).toUpperCase()
}()
<h4>總結(jié)一下:</h4>
codestring:從第一次post之后的響應(yīng)中提取出來
gid: 有一個已知函數(shù)guideRandom 隨機產(chǎn)生,可以通過調(diào)用函數(shù)獲取
token:通過將gid帶入這鏈接https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1469844296412&class=login&gid=58DDBCC-672F-423D-9A02-688ACB9EB252&logintype=basicLogin&callback=bd__cbs__cmkxjj 獲取響應(yīng)中的token
rsakey:帶入gid和token 到https://passport.baidu.com/v2/getpublickey?token=69a056f475fc955dc16215ab66a985af&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1469844359188&gid=58DDBCC-672F-423D-9A02-688ACB9EB252&callback=bd__cbs__rn85cf從響應(yīng)中可以提取出來rsakey
<h5>今天的分享就到這里靡砌,下一篇繼續(xù)分析已脓。如果大家覺得還可以呀,記得分享呦通殃,也可以到我主頁關(guān)注我的信息度液。</h5>