Hi缤剧,大家好镊掖,歡迎大家觀看由IT貓之家打造的【網(wǎng)絡(luò)爬蟲教學(xué)】蟲師終極武器之Chromium定制開發(fā)系列教學(xué)文章的第六篇诵竭,如果您是第一次觀看本系列教程,請先移步到這里看完前面的文章后再回來哦念颈!大家在學(xué)習(xí)的過程中泉粉,有任何疑問可以留言或加入我們的QQ技術(shù)交流群進行探討: 544185435
前言
前面我們已經(jīng)實現(xiàn)了多個FP重點檢測對象的接口隨機化,事實上只要完成這些接口的重寫就足以應(yīng)付大多網(wǎng)站了榴芳,不過我們既然要定制就做足全套吧嗡靡,在FP檢測腳本中,尚且還有一些也算是較為重要的判斷依據(jù)窟感,如:系統(tǒng)字體檢測讨彼、瀏覽器插件(plugins) 檢測、以及非人為觸發(fā)事件檢測isTrusted等柿祈。
FontStyle 隨機化的實現(xiàn)
由于每臺設(shè)備的字體可能存在差異等原因使得第三方服務(wù)可以輕松的通過獲取字體來判斷請求的客戶端是否為同一客戶端哈误,我們知道Chromium為了規(guī)避安全的風(fēng)險,不對JS提供太多的可用權(quán)限躏嚎,比如字體讀取蜜自,JS本不具備這種檢測權(quán)限,但FP巧妙的利用了字體的(長紧索、寬袁辈、描邊)等屬性來精確的判斷出客戶端是否包含了哪些字體,最終導(dǎo)出一串哈希值以便于作為有力的憑證珠漂,另除了這種方式晚缩,F(xiàn)P還通過Flash接口來調(diào)用字體進行判斷(需瀏覽器支持)
對于系統(tǒng)字體接口的隨機,我們可以從傳入的font-Style著手媳危,在之前的Canvas隨機方案中荞彼,我們有做過類似的操作,就直接篡改傳入的Style待笑,而對于字體我們也是可以這么干的鸣皂,只需將其替換成指定的字體即可。
要想實現(xiàn)該接口的隨機化,我們首先得要搞懂網(wǎng)站對這個接口的檢測是如何實現(xiàn)的以及它是如何運作的寞缝,而最好最直接的方法就是直接從目標網(wǎng)站分析并找到答案癌压,我們可以打開browserleaks?然后在關(guān)鍵處下斷點,從上圖我們可以看到它預(yù)設(shè)了一堆的常見字體荆陆。
從上圖滩届,我們可以看到一串:mmm?▁????????mmmmmmmlli 這樣的字符,在我接觸過的腳本中它們都會以這種形式作為檢測的基準被啼,至于為何一定要用這給字符串帜消,大家可以參考下這篇文章,這位大佬已經(jīng)解釋得很清楚:JavaScript/CSS Font Detector | JavaScript / CSS 字體檢測器
從圖中我們可以看出浓体,它每次循環(huán)都會通過接口style.fontFamily來為當(dāng)前標簽設(shè)置字體并獲取其寬度與高度泡挺,進而與原始的字體進行一一比對,一旦不相等則表示該字體存在命浴,通過該方法幾乎可以100%的測得準確結(jié)果娄猫,而我們要想實現(xiàn)該接口的隨機化,可以考慮從兩個點著手咳促,首先稚新,就像前面說的,接口每次都會通過 style.fontFamily 來設(shè)置字體跪腹,那么我們完全可以在這里進行篡改褂删,只要保證每次傳入的字體都不一致,則表示肯定會與結(jié)果有出入從而達到了隨機化的目的冲茸,其二屯阀,既然它是通過字體的寬度與高度來判斷是否成立的,那么我們也可以hook該接口返回隨機偏移的數(shù)值轴术,從而達到隨機化的目的难衰。
通過API查詢,我們可以很方便的找到該接口的路徑逗栽,我們只需按自己的需求實現(xiàn)隨機化即可盖袭,在這,我建議大家直接修改它的頭文件彼宠,因為我嘗試修改cc文件并未成功鳄虱,當(dāng)然大家也可以自行嘗試,萬一是我操作姿勢不對呢凭峡,啊哈哈….
plugins 接口隨機化的實現(xiàn)
事實上拙已,單單依賴這個插件指紋,服務(wù)端是無法判斷出是否同一客戶端的摧冀,也就是說只要完成前面的所有指紋偽造倍踪,基本上可以瞞天過海了系宫,但為了滿足部分強迫癥的看官,我還是有必要將這個給拉出來講解了建车。
我們直接在控制臺中輸入:navigator.plugins扩借,來看看這個插件到底包含了什么
我們可以看到,基本上 navigator.plugins 的子項包含了:四個字段以及2個對象(事實上是一個對象)癞志,而事實上我們?yōu)g覽器里的這個對象基本上都是一樣的往枷,所以我開頭說可以忽略掉這個接口,我們可以查看每個子項凄杯,可以發(fā)現(xiàn)它的字段是一樣的,同樣包含了: name秉宿、 filename 戒突、 description 、 MimeType 描睦;那么這樣就好辦了膊存,直接從以上的字段著手即可。
通過API查詢忱叭,我們定位到這個 navigator.plugins 的接口位于:third_party\blink\renderer\modules\plugins目錄下隔崎,我們只需對其實現(xiàn)隨機化即可。
上圖是插件隨機化后的效果韵丑,經(jīng)過篡改:String DOMPlugin::name()爵卒、String DOMPlugin::filename()、String DOMPlugin::description()我們可以很輕松的便實現(xiàn)了該接口的隨機化撵彻。
接口事件觸發(fā)之底層篡改大法
在FP腳本檢測的過程中钓株,還有一項作為檢測最為重要的評判指標 “isTrusted”,之所以將它留到最后講陌僵,是為了體現(xiàn)它的價值與其重要性轴合,該字段通常會出現(xiàn)在事件被觸發(fā)的時,它也是唯一的一個不可直接通過JS語法進行篡改的字段碗短,也就是說前面介紹的所有接口其實我們都是可以通過JS去篡改的受葛,(篡改是沒問題,但不見得一定能用偎谁,因為部分網(wǎng)站是有針對這個進行檢測的)总滩,而這個 “isTrusted ”則是例外。
我們來看看上圖搭盾,我們隨便定義了一個鼠標事件以及坐標的事件咳秉,然后我們可以發(fā)現(xiàn),它們都攜帶了一個“ isTrusted ”的字段鸯隅,并且它的值為false澜建,通過上圖我們可以發(fā)現(xiàn)向挖,這個接口并不能重寫,因為它是只讀的炕舵,覆蓋不了何之,而我也有嘗試過在茫茫網(wǎng)海中尋找可通過JS改寫的方案,最終都以失敗告終咽筋,當(dāng)然溶推,也有老外告訴我,它們可以通過配合擴展插件去實現(xiàn)奸攻,但必須得借助debugger來實現(xiàn)蒜危,并且無法取消彈窗,而這方法我也嘗試過睹耐,是成功了辐赞,但是及其耗資源,所以我才打算將其以基于底層的方式實現(xiàn)硝训。
我們再來看看真實觸發(fā)事件的情況响委,我們從上圖中可以看出,當(dāng)我們以真實鼠標去觸發(fā)它窖梁, “ isTrusted ” 是為真的赘风,而部分網(wǎng)站以該字段作為判斷的依舊,從而判斷你是否為機器人纵刘;事實上這個接口并不屬于是否同一客戶端的判斷范疇邀窃,而是為了校驗客戶端是否人為發(fā)起的請求。
Event接口的isTrusted是一個Boolean類型的只讀屬性.當(dāng)事件由用戶操作生成時為true彰导,由腳本創(chuàng)建或修改,或通過調(diào)用EventTarget.dispatchEvent生成,為false蛔翅;從這里我們可以看到通過腳本創(chuàng)建或者修改的都會返回false,從而我們可以更加肯定這個字段是肯定會被網(wǎng)站作為重要的判斷依舊的位谋。
通過API我們順藤摸瓜的找到了接口的路徑山析,并將其篡改為true,而掏父,因為所有的事件(如:MouseEvent笋轨、PointEvent) 都是派生與event ,所以一旦在其根源修改了赊淑,所有的事件都勢必會返回真爵政,從而達到我們想要的目的。
最后陶缺,附上一張篡改后的效果圖钾挟,以表示成功。
作者寄語
感謝大家一直閱讀本系列文章饱岸,到本文為止掺出,我們已經(jīng)實現(xiàn)了FP里的大部分檢測徽千,而通過這些屬性的偽造,我們已經(jīng)可以在大部分網(wǎng)站上執(zhí)行了汤锨,而由于接口都是隨機的双抽,所以網(wǎng)站無法確認是否為同一客戶端,從而達到了真正的匿名效果闲礼;但部分網(wǎng)站還是采用的Cookie形式來記錄的牍汹,所以,我們也可以通過隱身模式或者通過第三方擴展來屏蔽柬泽。另外慎菲,請大家不要再私下問我怎么不完全把接口暴露出來,之類的話锨并,首先钧嘶,一旦方法暴露,勢必會遭到第三方網(wǎng)站進行特征收集琳疏,沒有什么是絕對的,收集過多的數(shù)據(jù)闸拿,照樣可以判斷你是機器人空盼,或者直接屏蔽你的瀏覽器,其二新荤,研究是需要時間與精力的揽趾,如果大家都是抱著做伸手黨的心思來討要結(jié)果,那么您可能找錯方向了苛骨,天天研究頭發(fā)都白了篱瞎,你伸下手就想要,有這么好的事歡迎留言告訴我痒芝,我也想要俐筋;最后如果大家有業(yè)務(wù)需求可以找我合作,JS逆向或瀏覽器定制均可严衬。