尋找阿登高地——爬蟲(chóng)工程師如何繞過(guò)驗(yàn)證碼

馬奇諾防線(xiàn)是二戰(zhàn)前法國(guó)耗時(shí)十余年修建的防御工事,十分堅(jiān)固,但是由于造價(jià)昂貴,僅修建了法德邊境部分,綿延數(shù)百公里,而法比邊界的阿登高地地形崎嶇,不易運(yùn)動(dòng)作戰(zhàn),且比利時(shí)反對(duì)在該邊界修建防線(xiàn),固法軍再次并沒(méi)過(guò)多防備,滿(mǎn)心期望能夠依靠堅(jiān)固的馬奇諾防線(xiàn)來(lái)阻擋德軍的攻勢(shì)。沒(méi)想到后來(lái)德軍避開(kāi)德法邊境正面,通過(guò)阿登高地從防線(xiàn)左翼迂回,繞過(guò)了馬奇諾防線(xiàn),然后就是英法聯(lián)軍的敦克爾克大撤退了。

網(wǎng)站驗(yàn)證碼就如同馬奇諾防線(xiàn)一樣,阻擋了爬蟲(chóng)工程師的正面進(jìn)攻。

隨著爬蟲(chóng)和反爬蟲(chóng)雙方圍繞驗(yàn)證碼的不斷較量,最終導(dǎo)致了驗(yàn)證碼識(shí)別難度的不斷上升?,F(xiàn)在復(fù)雜的驗(yàn)證碼長(zhǎng)這樣:

正面硬剛驗(yàn)證碼,想要識(shí)別它,是件挺復(fù)雜的事,涉及到圖像處理技術(shù):二值化,降噪,切割,字符識(shí)別算法:KNN(K鄰近算法)和SVM (支持向量機(jī)算法),再?gòu)?fù)雜點(diǎn)還要借助CNN(卷積神經(jīng)網(wǎng)絡(luò)),還有什么機(jī)器學(xué)習(xí)啥的。

雖然現(xiàn)在有打碼平臺(tái)可以解決絕大多數(shù)的驗(yàn)證碼問(wèn)題,但如果爬取的數(shù)量特別龐大,單純依賴(lài)打碼平臺(tái)也是不大行得通的,除了成本因素,還有打碼平臺(tái)也解決不了的驗(yàn)證碼因素,比如滑動(dòng)驗(yàn)證碼:


既然正面進(jìn)攻費(fèi)事費(fèi)力,那能不能找到爬蟲(chóng)工程師眼中的阿登高地繞過(guò)驗(yàn)證碼呢?

本文以各地工商網(wǎng)站為例,對(duì)常見(jiàn)的驗(yàn)證碼繞過(guò)技巧做一個(gè)小總結(jié),順便解密下如何不借助模擬js拖動(dòng)來(lái)繞過(guò)滑動(dòng)驗(yàn)證碼。

各地工商網(wǎng)站(全稱(chēng)國(guó)家企業(yè)信用信息公示系統(tǒng))因?yàn)榘罅科髽I(yè)真實(shí)信息,金融貸款征信等都用得到,天然吸引了很大部分來(lái)自爬蟲(chóng)的火力,因此反爬蟲(chóng)措施格外嚴(yán)格。一般的網(wǎng)站僅在登錄注冊(cè)等環(huán)節(jié),或者訪(fǎng)問(wèn)頻繁后才彈出驗(yàn)證碼,而工商網(wǎng)站查詢(xún)無(wú)需登錄,每查一次關(guān)鍵字就需要一次驗(yàn)證碼。同時(shí)各地工商網(wǎng)站由于各自獨(dú)立開(kāi)發(fā),自主采用了各種不同的驗(yàn)證碼機(jī)制,更是給全量爬取的爬蟲(chóng)增加了更多的障礙。因此,工商網(wǎng)站的驗(yàn)證碼特別具有代表性。

首先,從最簡(jiǎn)單的分頁(yè)角度入手。

分頁(yè)的處理可以放在前端也可以放在后端,如果只放在后端,每次點(diǎn)擊頁(yè)碼就需要發(fā)送一次查詢(xún)請(qǐng)求,而一次驗(yàn)證碼通常只能服務(wù)于一次請(qǐng)求,再次請(qǐng)求需要獲取新的驗(yàn)證碼,直接觀(guān)察翻頁(yè)操作是否彈出驗(yàn)證碼輸入框即可判斷是否可以繞過(guò)。

如何判斷分頁(yè)處理放在前端還是后端的呢?很簡(jiǎn)單,F(xiàn)12打開(kāi)瀏覽器開(kāi)發(fā)者工具,頁(yè)面點(diǎn)下一頁(yè),有新的請(qǐng)求就說(shuō)明放在后端,反之就是前端。

實(shí)踐發(fā)現(xiàn),四川和上海的工商網(wǎng)站翻頁(yè)都放在后端,且翻頁(yè)沒(méi)有驗(yàn)證碼輸入框。說(shuō)明這里的驗(yàn)證碼可以繞過(guò),但是繞過(guò)的原理卻有些不同:

l對(duì)比四川工商網(wǎng)站翻頁(yè)前后請(qǐng)求的參數(shù),除了頁(yè)碼參數(shù)外,多了一項(xiàng):yzmYesOrNo=no。從變量名也猜得到,后端根據(jù)該參數(shù)的值判斷是否需要檢查驗(yàn)證碼。

l而上海工商網(wǎng)站的對(duì)比結(jié)果發(fā)現(xiàn),除了頁(yè)碼參數(shù)外,少了驗(yàn)證碼字段,因此我們可以大膽猜測(cè):驗(yàn)證碼的校驗(yàn)僅放在了前端,后端沒(méi)有做二次校驗(yàn),從頁(yè)面上操作是繞不過(guò)的,但是不帶驗(yàn)證碼字段直接向后端發(fā)送請(qǐng)求,數(shù)據(jù)就拿到了。

嚴(yán)格來(lái)說(shuō),上海工商網(wǎng)站這種算是漏洞,對(duì)待這種這種漏洞,爬蟲(chóng)工程師應(yīng)有的態(tài)度是:悄悄的進(jìn)村,打槍的不要。不過(guò)也不要利用的太狠了,筆者實(shí)驗(yàn)時(shí)沒(méi)加限制,爬了十萬(wàn)數(shù)據(jù)后,ip被封了。很長(zhǎng)時(shí)間后才解封,同時(shí)頁(yè)面改版并修復(fù)了漏洞。


其次,觀(guān)察目標(biāo)網(wǎng)站是否有多套驗(yàn)證碼。

有些網(wǎng)站不知道出于什么樣的考慮,會(huì)在不同的頁(yè)面使用不同的驗(yàn)證碼。一旦遇到這種情況,我們可就要撿軟柿子捏了--從簡(jiǎn)單的驗(yàn)證碼入手,移花接木,將識(shí)別的結(jié)果作為參數(shù)來(lái)向后端發(fā)送請(qǐng)求,從而達(dá)到繞過(guò)復(fù)雜驗(yàn)證碼的目的。

舉例來(lái)說(shuō),湖北工商的查詢(xún)頁(yè)面驗(yàn)證碼是類(lèi)似下圖的九宮格驗(yàn)證碼:


而電子營(yíng)業(yè)執(zhí)照登陸界面的驗(yàn)證碼是這樣的:


即便要識(shí)別,也明顯是后者的驗(yàn)證碼要容易些,實(shí)例代碼如下:

再者,可以考慮從數(shù)據(jù)的存儲(chǔ)id入手

專(zhuān)門(mén)針對(duì)移動(dòng)端開(kāi)發(fā)的wap頁(yè)面限制一般要少得多。以北京工商網(wǎng)站來(lái)說(shuō),wap界面不帶驗(yàn)證碼參數(shù)直接發(fā)送請(qǐng)求就可以得到數(shù)據(jù)的,原理類(lèi)似于上海工商網(wǎng)站,但是其對(duì)單個(gè)ip日訪(fǎng)問(wèn)次數(shù)做了嚴(yán)格限制,因此該方式可以用但不好用。

繼續(xù)觀(guān)察,以搜索“山水集團(tuán)”為例,從搜索頁(yè)到列表頁(yè)時(shí),需要輸入驗(yàn)證碼,而從列表頁(yè)進(jìn)入詳情頁(yè)的時(shí)候,是不需要驗(yàn)證碼的。最終詳情頁(yè)如圖:

通常沒(méi)人記得住各地工商網(wǎng)站的網(wǎng)址,我們會(huì)去搜索引擎里搜。當(dāng)搜北京企業(yè)信用信息時(shí),發(fā)現(xiàn)兩個(gè)有價(jià)值的結(jié)果,除了國(guó)家企業(yè)信用信息公示系統(tǒng)外,還有個(gè)北京市企業(yè)信用信息信息網(wǎng)。進(jìn)后者再操作一番可以得到下面的詳情頁(yè):

觀(guān)察發(fā)現(xiàn),企業(yè)id都是相同的,嘿嘿,這不是“兩塊牌子,一套班子”嘛!后者的訪(fǎng)問(wèn)量要小一些,雖有驗(yàn)證碼,但是可以采用上海工商一樣的方式繞過(guò),只是返回的結(jié)果字段不太符合我們的要求。不過(guò),我們可以去企業(yè)信息網(wǎng)獲得企業(yè)id,再次采用移花接木的方式,去信息公示系統(tǒng)構(gòu)造鏈接獲得最終的詳情頁(yè)嘛!

用過(guò)數(shù)據(jù)庫(kù)同學(xué)都曉得,數(shù)據(jù)庫(kù)里的數(shù)據(jù)id,默認(rèn)是自增的。如果有個(gè)網(wǎng)站引用的數(shù)據(jù)是xxx.com?id=1234567, 那我們很容易猜得到構(gòu)造類(lèi)似1234568這樣的id去嘗試!通常,使用這種id規(guī)律能夠輕易猜出來(lái)的網(wǎng)站并不多,但不代表沒(méi)有。比如甘肅省工商網(wǎng)站,結(jié)果頁(yè)是拿企業(yè)注冊(cè)號(hào)來(lái)查詢(xún)的。

最后,談?wù)劵瑒?dòng)驗(yàn)證碼。

目前,工商網(wǎng)站已經(jīng)全面改版,全部采用了滑動(dòng)驗(yàn)證碼,上面絕大多數(shù)思路都失效了。對(duì)于滑動(dòng)驗(yàn)證碼,網(wǎng)上能搜到的解決方案基本都是下載圖片,還原圖片,算出滑動(dòng)距離,然后模擬js來(lái)進(jìn)行拖動(dòng)解決,我們來(lái)看下能否不模擬拖動(dòng)來(lái)解決這個(gè)問(wèn)題。

以云南工商網(wǎng)站為例,首先抓包看過(guò)程。

1.http://yn.gsxt.gov.cn/notice/pc-geetest/register?t=147991678609,response:


2.下載驗(yàn)證碼圖片


3.http://yn.gsxt.gov.cn/notice/pc-geetest/validate, post如下數(shù)據(jù):


4.http://yn.gsxt.gov.cn/notice/search/ent_info_list,post如下數(shù)據(jù):

仔細(xì)分析,我們發(fā)現(xiàn)兩處疑點(diǎn)

1. 第一步并沒(méi)有返回需要下載的圖片地址,那么前端怎么知道要下載哪些圖片?

2. 第三步驗(yàn)證時(shí),并沒(méi)有告知后端下載了那些圖片,后端是怎么驗(yàn)證post過(guò)去的數(shù)據(jù)是有效性的?

仔細(xì)閱讀前端混淆的js代碼,我們發(fā)現(xiàn)前端數(shù)據(jù)處理過(guò)程是這樣的:

1. 從0到6(不含)中取隨機(jī)整數(shù),賦值給d, d=5;

2. 從0到300(不含)中取隨機(jī)整數(shù),賦值給e, e=293;

3. 將d轉(zhuǎn)化為字符串并作MD5加密,加密字符串取前9位賦值給f, f='e4da3b7fb';

4. 將e轉(zhuǎn)化為字符串并作MD5加密,加密字符串從第11位開(kāi)始取9位賦值給g, g='43be4f209';

5. 取f的偶數(shù)位和g的奇數(shù)位組成新的9位字符串給h, h='e3de3f70b';

6. 取h的后4位與200做MOD運(yùn)算,其結(jié)果小于40,則取40,否則取其本身賦值給x,x=51;

7. 取[x-3, x+3]以?xún)?nèi)隨機(jī)數(shù)賦值給c,c=51;

8. 分別取c,d,e跟challenge做t加密(t(c,challenge), t(d, challenge), t(e,challenge))并用(_)拼接即為geetest_validate, '9ccccc997288_999c9ccaa83_999cc9c9999990d'

這里f, g參數(shù)決定了下載圖片地址:

而x為滑塊拖動(dòng)的橫向偏移量,至此解答了疑問(wèn)1中圖片下載地址怎么來(lái)的問(wèn)題。

前邊提到的t加密過(guò)程是這樣的:


t(a,b),此處以a=51演示

1. challenge為34位16進(jìn)制字符串,取前32位賦值給prefix,后2位賦值給suffix,prefix='34173cb38f07f89ddbebc2ac9128303f', suffix='a8'

2. prefix去重并保持原順序,得到列表 ['3', '4', '1', '7', 'c', 'b', '8', 'f', '0', '9', 'd', 'e', '2', 'a']

3. 將2中列表循環(huán)順序放入包含5個(gè)子列表的列表中,得到random_key_list:? [['3', 'b', 'd'], ['4', '8', 'e'], ['1', 'f', '2'], ['7', '0', 'a'], ['c', '9']]

4. 將suffix字符串(16進(jìn)制)逐位轉(zhuǎn)化為10進(jìn)制,得到[10, 8]

6. 將4中列表逐位與[36,0]做乘法和運(yùn)算并與a的四舍五入結(jié)果相加, n= 51 + 36*10 + 0*8=419

7. q=[1,2,5,10,50], 用q對(duì)n做分解(n=50*13+10*0+5*1+2*1+1*1),將其因數(shù)倒序賦值給p,p=[0,2,1,1,8]

8. 從random_key_list右側(cè)開(kāi)始隨機(jī)取值,次數(shù)為p中數(shù)值,拼成字符串sub_key,sub_key='9ccccc997288'

至此,我們完成了整個(gè)分析過(guò)程,我們又有了新發(fā)現(xiàn):

1. 按照前邊的抓包過(guò)程,其實(shí)不需要真的下載圖片,只需執(zhí)行1、3、4步就可以得到目標(biāo)數(shù)據(jù)了。步驟1也可以不要,只需3、4即可,但是少了步驟1, 我們還需要額外請(qǐng)求一次cookie,所以還是保留1, 這樣也偽裝的像一點(diǎn)嘛。

2. 相同的challenge,每次運(yùn)算都可以得出不同的validate和seccode,那么問(wèn)題來(lái)了:到底服務(wù)端是怎么根據(jù)challenge驗(yàn)證其他數(shù)據(jù)是否有效呢?

總結(jié)一下,對(duì)于驗(yàn)證碼,本文只是提供了一種新的思路,利用了網(wǎng)站開(kāi)發(fā)過(guò)程中的一點(diǎn)小疏漏,而最后的滑動(dòng)驗(yàn)證碼也只是分析了offline模式的驗(yàn)證方法。不要指望所有驗(yàn)證碼都可以能繞過(guò),沒(méi)有阿登高地,二戰(zhàn)德國(guó)就不打法國(guó)了么?只要覺(jué)得有價(jià)值,即使正面面對(duì)驗(yàn)證碼,作為爬蟲(chóng)工程師建議也就一句話(huà):不要慫,就是干!

本文作者:候克雷(點(diǎn)融黑幫),就職于點(diǎn)融成都Data Team,爬蟲(chóng)開(kāi)發(fā)工程師。主要負(fù)責(zé)工商爬蟲(chóng),運(yùn)營(yíng)商爬蟲(chóng),輿情監(jiān)控等項(xiàng)目開(kāi)發(fā)。測(cè)試出身,做過(guò)自動(dòng)化,寫(xiě)過(guò)后端,人生苦短,我用Python。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評(píng)論 19 139
  • 爬蟲(chóng)是一個(gè)比較容易上手的技術(shù),也許花5分鐘看一篇文檔就能爬取單個(gè)網(wǎng)頁(yè)上的數(shù)據(jù)。但對(duì)于大規(guī)模爬蟲(chóng),完全就是另一回事,...
    真依然很拉風(fēng)閱讀 9,823評(píng)論 5 114
  • 別人講山的那邊是海,是信念凝成的海。小時(shí)候的我相信了,我以為山的那邊風(fēng)景肯定很漂亮,我特別期待,可是我始終都沒(méi)登上...
    秋風(fēng)一笑閱讀 784評(píng)論 0 2
  • 我有一個(gè)表哥,如果不是某天他加我微信后,隔三差五就私聊發(fā)養(yǎng)生保健的內(nèi)容給我,幾乎就忘了還有這么個(gè)表哥。 周五接到表...
    海上鯨歌閱讀 338評(píng)論 0 1
  • 1.注冊(cè) GitHub 賬號(hào), 把github用戶(hù)名發(fā)送給老師。 賬號(hào):hansuze 2.看Git的使用視頻,安...
    我是小韓閱讀 1,172評(píng)論 0 0

友情鏈接更多精彩內(nèi)容