聲明
1.所謂的自動(dòng)識(shí)別谷歌驗(yàn)證碼并不是真正的利用人工智能去識(shí)別谷歌驗(yàn)證碼钟鸵,在本文章中只是對(duì)接某國(guó)外的驗(yàn)證碼識(shí)別平臺(tái)來(lái)達(dá)到自動(dòng)識(shí)別的效果票彪,其目的就是為了學(xué)習(xí)下xposed而已账阻。
2.有哪里說(shuō)的不對(duì)的地方還請(qǐng)大家多多指教,本博主郵箱?itdreamlmc@163.com
3.版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得私自轉(zhuǎn)載者吁。
前言
????????本博主作為一個(gè)屌絲java程序猿在業(yè)余時(shí)間總是閑著無(wú)聊想逆向搞些app拿來(lái)發(fā)泄下讳窟,一方面是為了提高自己編程上的安全意識(shí)让歼,另一方面也是出于愛好。這不丽啡,就在周六的時(shí)候一個(gè)朋友就發(fā)了我這個(gè)國(guó)外某網(wǎng)絡(luò)電話的app是越,這個(gè)app有的時(shí)候登錄會(huì)出現(xiàn)谷歌的 ?I am not a robot?驗(yàn)證碼,類似國(guó)內(nèi)12306的驗(yàn)證碼碌上,我朋友發(fā)我之后問(wèn)我能不能自動(dòng)識(shí)別這個(gè)驗(yàn)證碼倚评,不用麻煩的每次都取驗(yàn)證。之后我就?google 了一番馏予,偶然發(fā)現(xiàn)了?https://2captcha.com/?這個(gè)強(qiáng)大的驗(yàn)證碼識(shí)別平臺(tái)天梧,居然可以自動(dòng)識(shí)別谷歌的驗(yàn)證碼。于是看了下官方的api文檔霞丧,發(fā)現(xiàn)對(duì)接這個(gè)平臺(tái)識(shí)別谷歌驗(yàn)證碼只需要調(diào)用他們的接口給他們傳一個(gè)k值呢岗,然后返回一個(gè)id,之后過(guò)幾秒鐘之后用id去請(qǐng)求另外一個(gè)接口獲取識(shí)別結(jié)果蛹尝,然后將識(shí)別結(jié)果填寫到頁(yè)面的textarea的 value中驗(yàn)證就行了后豫。
那么問(wèn)題來(lái)了
1.要做識(shí)別的是一個(gè) app,我們要怎么拿到k值呢突那?
2.我們拿到三方平臺(tái)的識(shí)別結(jié)果又怎么給他設(shè)置并顯示到app端呢挫酿?
這個(gè)時(shí)候就想起了四哥的文章,利用xposed 可以hook任意app的某偶些方法實(shí)現(xiàn)愕难。于是就開始了我的hook之旅..........
抓包分析
????????還是老套路早龟,拿到app之后,管他是什么鳥app猫缭,直接抓他網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)包然后簡(jiǎn)單大體上分析分析這種驗(yàn)證碼圖片是怎么返回的葱弟?又是怎么驗(yàn)證的?然后去想想解決方案猜丹。
1.首先打開抓包神器Fiddler芝加,然后打開模擬器設(shè)置好代理ip跟端口(注:需要配置好Fiddler的證書,因?yàn)?這個(gè)app的驗(yàn)證碼是google驗(yàn)證碼射窒,自然所有的網(wǎng)絡(luò)請(qǐng)求都是https的藏杖,如果你不設(shè)置fiddler證書将塑,那么自然就抓不到他的請(qǐng)求數(shù)據(jù)包了)。然后打開app登錄賬號(hào)我們會(huì)看到如下請(qǐng)求數(shù)據(jù)跟驗(yàn)證碼制市。(本來(lái)想著抓app的驗(yàn)證碼了抬旺,結(jié)果可到好,今天死活也不出驗(yàn)證碼了祥楣,我就找來(lái)下網(wǎng)頁(yè)的驗(yàn)證碼做個(gè)參考开财,驗(yàn)證碼都是一樣的)
我們抓到數(shù)據(jù)之后按照識(shí)別平臺(tái)的要求需要找到一個(gè)k值,跟出現(xiàn)驗(yàn)證碼的頁(yè)面鏈接然后提供給他們误褪,之后就可以了责鳍。分析下抓 到的請(qǐng)求數(shù)據(jù),我們可以看到對(duì)接谷歌驗(yàn)證碼的sdk都會(huì)有個(gè)鏈接兽间,且里面有k值历葛,如圖所示。
打開?https://2captcha.com/2captcha-api?識(shí)別平臺(tái)api文檔嘀略,找到接口說(shuō)明如圖所示
請(qǐng)求接口
http://2captcha.com/in.php?key=1abc234de56fab7c89012d34e56fa7b8&method=userrecaptcha&googlekey=6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-&pageurl=http://mysite.com/page/with/recaptcha?appear=1&here=now
key:對(duì)接平臺(tái)的token令牌恤溶,申請(qǐng)之后就可以看到
googlekey:就是上邊所說(shuō)的k值
pageurl:就是顯示驗(yàn)證碼的頁(yè)面地址
拼接好參數(shù)之后,請(qǐng)求接口會(huì)給我們返回一個(gè)id帜羊,之后延遲幾秒鐘之后我們在訪問(wèn)接口
http://2captcha.com/res.php?key=1abc234de56fab7c89012d34e56fa7b8&action=get&id=2122988149
key:對(duì)接平臺(tái)的token令牌咒程,申請(qǐng)之后就可以看到
id:請(qǐng)求接口一返回的ID
獲取響應(yīng)結(jié)果如圖所示
拿到結(jié)果之后我玩?zhèn)冊(cè)诮o頁(yè)面的textAreay設(shè)置value值為這個(gè),這樣可以通過(guò)驗(yàn)證了讼育。
Hook WebView搞定app自動(dòng)識(shí)別
????????上邊說(shuō)了一大堆廢話帐姻,其實(shí)就是一個(gè)簡(jiǎn)單的思路分析。如果我要達(dá)到自動(dòng)識(shí)別的效果奶段,其實(shí)最終就是給驗(yàn)證碼頁(yè)面里這個(gè)textarea 屬性設(shè)置上驗(yàn)證碼的值就行了饥瓷。那么問(wèn)題來(lái)了,app都是自動(dòng)去請(qǐng)求谷歌的驗(yàn)證碼痹籍,我們要怎么拿到請(qǐng)求的連接呢铆,有怎么去自定義響應(yīng)數(shù)據(jù)呢?剛看到這個(gè)app的時(shí)候词裤,為以為這個(gè)驗(yàn)證碼就應(yīng)該是一個(gè)圖片刺洒,也是應(yīng)該是imageview顯示的,之后分析了分析吼砂,發(fā)現(xiàn)不并不是。之后Google了一番鼎文,才知道顯示這個(gè)驗(yàn)證碼的頁(yè)面就是一個(gè)webview渔肩,對(duì)于我一個(gè)搞后來(lái)java的程序猿來(lái)說(shuō),對(duì)安卓自然也不是很懂拇惋,然后又不想放棄周偎,所有就想到了xposed這個(gè)吊炸天的框架抹剩,既然webview能顯示內(nèi)容,那么肯定是通過(guò)某個(gè)方法蓉坎,獲取url連接澳眷,然后請(qǐng)求網(wǎng)絡(luò)資源,拿到輸入流顯示數(shù)據(jù)蛉艾。所以說(shuō)钳踊,只要我們知道webview的獲取url跟響應(yīng)數(shù)據(jù)的方法,那么我們就可以通過(guò)xposed去hook這個(gè)方法勿侯,然后就可以輕松的獲取參數(shù)響應(yīng)數(shù)據(jù)了拓瞪。
? ? ? ? Google了下,就看了這篇文章?http://blog.csdn.net/qq_19431333/article/details/52351437?助琐,才發(fā)現(xiàn)webview請(qǐng)求網(wǎng)絡(luò)資源的時(shí)候祭埂,都會(huì)調(diào)用?shouldInterceptRequest 這個(gè)方法,如果這個(gè)方法的輸入流不為空兵钮,則直接獲取輸入流顯示數(shù)據(jù)蛆橡,如果這個(gè)輸入流為空,那么webview 就通過(guò)url去請(qǐng)求真正的網(wǎng)絡(luò)資源掘譬。既然是這個(gè)樣子泰演,那么我們是不是可以來(lái)hook這個(gè)方法,來(lái)判斷url是不是我們想要的url屁药,如果這個(gè)url有k值 那么我們就去獲取這個(gè)k保存下來(lái)粥血,如果這個(gè)url是驗(yàn)證碼頁(yè)面的url,我們攔截下酿箭,通過(guò)url獲取網(wǎng)絡(luò)資源复亏,然后通過(guò)第一步保存的k值去請(qǐng)求三方平臺(tái),拿到識(shí)別結(jié)果才替換進(jìn)去缭嫡,給app響應(yīng)自然就完成了識(shí)別缔御。下邊是具體實(shí)現(xiàn)。
開啟webview允許js調(diào)用妇蛀,允許js彈窗
webView.post(new Runnable() {
@Override
public void run() {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
}
});
調(diào)用三方接口獲取識(shí)別接口
給textarea設(shè)置屬性(這里是插入一段 js代碼耕突,獲取textare document對(duì)象進(jìn)行設(shè)置)
String replace = string.replace(oldStr, "測(cè)試提交啊");String jsText = "mytoken='"+ globaToken+ "';"+ "function testCall(){alert('success');document.getElementById(\"g-recaptcha-response\").innerHTML=mytoken;}";replace = replace.replace("", jsText + "\n");WebResourceResponse webResourceResponse = new WebResourceResponse("text/html","utf-8", new ByteArrayInputStream(replace.getBytes()));param.setResult(webResourceResponse);
之后打包apk按照到手機(jī)上就可以了。
收工评架,講的不好請(qǐng)多多關(guān)照眷茁。