文/張凱
全球數(shù)百萬人使用廣告攔截器刪除惡意廣告,并防止因?yàn)閺V告追蹤造成個(gè)人隱私泄露。而對于大多數(shù)提供免費(fèi)在線內(nèi)容和服務(wù)的網(wǎng)站來說廣告收入是主要收入來源,故把廣告攔截器看做主要威脅,他們部署反廣告攔截器來檢測和阻止廣告攔截器。針對這種情況,廣告攔截器反過來檢測和過濾反廣告攔截的腳本,廣告攔截和反廣告攔截之間的軍備競賽在反復(fù)進(jìn)行。
文章Measuring and Disrupting 反廣告攔截器 Using Differential Execution Analysis發(fā)表于 NDSS 2018(原文作者:Shitong Zhu ,Xunchao Hu , Zhiyun Qian, Zubair Shafiq and Heng Yin),作者對反廣告攔截器進(jìn)行了全面分析,并幫助廣告攔截器對抗反廣告攔截器。在論文中,提出利用有差異的執(zhí)行分析方法自動檢測和分析反廣告攔截器。通過收集使用和未使用廣告攔截器的瀏覽器來訪問同一網(wǎng)站的執(zhí)行蹤跡,作者能指出存在分歧的分支及條件語句,而這些分歧因?yàn)榉磸V告攔截代碼引發(fā)的。利用此系統(tǒng),檢測到Alexa top-10K有30.5%的網(wǎng)站部署了反廣告攔截器軟件,與以往報(bào)道相比提高了5~52倍。早期工作僅檢測有明顯反應(yīng)的反廣告攔截器,這種系統(tǒng)對沒有明顯反應(yīng)的也能有效測量。通過對1/3被檢測的網(wǎng)站進(jìn)行分析,發(fā)現(xiàn)90%網(wǎng)站對廣告攔截器存在做出不明顯反應(yīng)。最后,基于這些知識,作者給出JavaScript rewriting和API hook兩種方法幫助攔截器繞過當(dāng)前反廣告攔截器。
廣告驅(qū)動的網(wǎng)站大部分在線內(nèi)容和服務(wù)都是免費(fèi)的,其大量在線廣告引發(fā)了嚴(yán)重的安全和隱私考慮。比如廣告商跨網(wǎng)追蹤用戶卻不給出任何提示,造成隱私暴露。攻擊者甚至利用廣告?zhèn)鞑阂廛浖虼撕芏嗳诉x擇部署廣告攔截器。廣告發(fā)布平臺因?yàn)閺V告攔截?fù)p失10多億美元的收入,因此部署反廣告攔截來檢測廣告攔截器,并提出不同應(yīng)對措施:
1.一些廣告發(fā)布商比如微軟和google,提出可接受的廣告程序,讓他們的廣告都列入白名單。小的發(fā)布商可以免費(fèi)注冊,但是中大規(guī)模的發(fā)布者必須支付他們的廣告費(fèi)。
2.一些廣告發(fā)布者,最明顯的是臉書,控制廣告讓廣告攔截更難移除它們,而廣告攔截器迅速趕上來并調(diào)整它們的規(guī)則來更好的攔截廣告。
3.許多廣告發(fā)布者部署反廣告攔截器,來檢測攔截器并對此客戶端作出相應(yīng)。通常反廣告攔截器強(qiáng)制用戶把網(wǎng)頁加入白名單或者禁用
當(dāng)前廣告攔截器依賴手工整理過濾列表來攔截廣告。廣告發(fā)布商操縱廣告交付來規(guī)避過濾列表。比如,更改域名和HTML元素標(biāo)識符來繞過過濾,這迫使過濾列表作者頻繁更新列表,工作量很大,研究者提出基于網(wǎng)絡(luò)流量分析的辦法(例如,識別廣告服務(wù)域名)自動升級過濾規(guī)則,這種辦法不能解決廣告發(fā)布商的HTML操縱。當(dāng)廣告攔截器更新規(guī)則來阻擋Facebook廣告,F(xiàn)acebook能夠繼續(xù)操縱它們的HTML繞過新的過濾規(guī)則。研究者提出一種有知覺的廣告攔截方法用于可見識別,攔截廣告使用可見字符識別,fuzzy圖像匹配技術(shù)。關(guān)鍵思想是,因?yàn)檎ㄒ?guī)和行業(yè)自律要求,廣告和網(wǎng)頁正常內(nèi)容是有區(qū)別的。
早期研究提出一些措施來檢測和規(guī)避Anti-blocker軟件。一種方法是提取反廣告攔截器腳本指紋,然而指紋不會自動生成和擴(kuò)展。手工分析代碼要比識別廣告有關(guān)的URL或者HTML元素困難的多。有研究者提出自動的靜態(tài)JavaScript代碼分析技術(shù)檢測惡意JavaScript腳本(基于語法和結(jié)構(gòu)分析)。但是這些技術(shù)準(zhǔn)確捕捉JavaScript行為很困難。因?yàn)镴avaScript代碼是動態(tài)的,并很容易進(jìn)行代碼混淆。
作者提出一種動態(tài)代碼分析方法對反廣告攔截器進(jìn)行大規(guī)模系統(tǒng)分析和描繪其行為特征,這里稱為執(zhí)行差異分析。其關(guān)鍵思想就是對網(wǎng)站進(jìn)行有廣告攔截器和無廣告攔截器情況進(jìn)行有差別的執(zhí)行分析。對于一個(gè)部署反廣告攔截器的網(wǎng)站,如果被安裝廣告攔截器的瀏覽器訪問,以及被未安裝廣告攔截器瀏覽器訪問,它會有不同的JAVASCRIPT執(zhí)行軌跡。也就是說,通過對比分析這同一個(gè)網(wǎng)站的不同執(zhí)行軌跡可以有助于發(fā)現(xiàn)網(wǎng)站是否部署反廣告攔截器軟件。

圖1 系統(tǒng)概況
作者開發(fā)了一個(gè)系統(tǒng)自動對網(wǎng)站訪問,對執(zhí)行軌跡進(jìn)行比較分析,找出存在分歧的分支及條件語句,檢測出該網(wǎng)站是否部署反廣告攔截軟件。系統(tǒng)概況如圖1所示。
反廣告攔截器腳本主要由兩個(gè)部分組成:(1)觸發(fā)器,它檢測廣告攔截器的存在;(2)反應(yīng)器,它能顯示廣告攔截器檢測消息,甚至給后臺服務(wù)器報(bào)告檢測結(jié)果。當(dāng)檢測到廣告攔截后,反廣告攔截器就會執(zhí)行一些額外語句,例如顯示警告消息或者發(fā)送統(tǒng)計(jì)數(shù)據(jù)給后端的服務(wù)器。由于關(guān)注的是JavaScript的控制流,所以系統(tǒng)僅收集了所有分支語句的跟蹤,以及跟蹤對齊所需的調(diào)用堆棧信息。這些信息送給差異執(zhí)行分析來識別兩種軌跡的條件分支,最后得到一個(gè)分支列表以及分支語句中的檢查條件。
已有的JavaScript執(zhí)行軌跡追蹤技術(shù)有三類:JavaScript rewriting、JavaScript debugger interface以及JavaScript enginebased 。論文選擇基于引擎的方法。這種方法不要求對JavaScript代碼做任何變動;對于反廣告攔截器這種方法透明,無法檢測。系統(tǒng)部署Chromium作為JavaScript引擎。Chromium V8對每個(gè)函數(shù)生成抽象語法樹,然后編譯成本地代碼。在本地代碼生成過程中,作者編寫的指令嵌入其中,指令收集一些資源映射信息(比如語句在腳本中的偏移位置)和JavaScript語句信息。通過修改JIT,在執(zhí)行本地代碼之前,首先執(zhí)行stub 代碼,它能夠在運(yùn)行時(shí)訪問內(nèi)聯(lián)的變量獲得已經(jīng)被執(zhí)行的JAVASCRIPT語句的信息。資源映射信息用作被執(zhí)行語句的ID,在執(zhí)行痕跡對齊時(shí)用到。
由于通過監(jiān)控控制流的差異來檢測反廣告攔截器,所以需要對所有分支語句要進(jìn)行記錄。常見分支有if/else ;switch/case;condition expr1∶expr2;for/while loop;try/catch;以及其它潛在的條件表達(dá)式。根據(jù)反廣告攔截器腳本最常見用法,選擇if/else 和條件表達(dá)式。為了對齊執(zhí)行痕跡需要記錄call/return 語句,堆棧信息中包含了它們調(diào)用的上下文語句信息。通過對廣告攔截器的filter list進(jìn)行配置以便最大程度發(fā)現(xiàn)Anti-blocker存在:禁用廣告白名單,不讓網(wǎng)站的任何廣告顯示;禁用警告刪除列表,一旦廣告被攔截允許顯示警告消息;刪除EasyList中針對Antiblocker的規(guī)則。這樣做的目的是讓反廣告攔截器軟件充分生效,以便觀察和研究。
為了保證精確對齊,使用堆棧信息,這兩個(gè)條件都必須滿足:一是兩個(gè)軌跡中所有語句的調(diào)用堆棧完全匹配;二是所有語句的標(biāo)識符完全匹配。
因?yàn)橥獠恳蛩乜梢詫?dǎo)致一個(gè)腳本出現(xiàn)不同執(zhí)行軌跡,比如因?yàn)闀r(shí)間,隨機(jī)資源等原因。為了避免無關(guān)原因造成的誤判。作者采用冗余執(zhí)行的方法,來克服測量中白噪聲問題。在實(shí)驗(yàn)中,作者生成3組positive軌跡,3組negative軌跡來檢測。測量一個(gè)網(wǎng)站所需要時(shí)間:因?yàn)闉g覽器加載擴(kuò)展后變慢,所以每次等待20秒后停止追蹤以確保網(wǎng)站完成加載。這樣運(yùn)行一次差異執(zhí)行分析平均大約3分鐘(positive和negative各測量三次)。

表1 基于不同源碼的Anti-adblocker腳本的主要來源
實(shí)驗(yàn)中使用一個(gè)32核心的服務(wù)器,在14個(gè)小時(shí)多一點(diǎn)就能處理10k個(gè)網(wǎng)站。因此利用此機(jī)器,系統(tǒng)分析Alexa top-10K一天時(shí)間就能完成。
該數(shù)據(jù)集(2017.2)包含686個(gè)安裝反廣告攔截器的網(wǎng)站,對此列表人工重新分析從中挑出428個(gè)網(wǎng)站,這些網(wǎng)站都部署反廣告攔截器,并對廣告攔截器能做出明顯的反應(yīng)。又從中人工選擇挑100個(gè)不包含廣告,也沒有部署反廣告攔截器軟件的網(wǎng)站。
測試表明系統(tǒng)達(dá)到86.9% (372/428) 準(zhǔn)確率,0% 誤報(bào)率;100 labeled negative websites, 沒有一個(gè)網(wǎng)站被錯(cuò)認(rèn)為部署反廣告攔截器。
測試結(jié)果表明30.5%網(wǎng)站部署Anti-adblocker。1238個(gè)使用if/else,473個(gè)使用選擇表達(dá)式,1344個(gè)包含兩者。反廣告攔截器數(shù)量比早先報(bào)道的要多,并不斷在增加。作者分析原因指出前期研究只關(guān)注有明顯反應(yīng)的情況,漏掉slient report。結(jié)果顯示排名越靠前網(wǎng)站,部署的越多。作者分析原因指出可能廣告是提供免費(fèi)在線信息和服務(wù)網(wǎng)站的重要收入來源。作者對反廣告攔截器腳本進(jìn)行分析,指出僅有422個(gè)網(wǎng)站使用自己的反廣告攔截軟件,其它2219個(gè)均采用第三方腳本。13個(gè)第三方反廣告攔截器腳本,Google腳本是最流行的,YouTube次之,Taboola,PageFair腳本使用者也很多。13個(gè)腳本中9個(gè)占了部署anti軟件的top-10k中1/3 ,悄悄檢查廣告攔截器和報(bào)告給后臺服務(wù)器。這些anti腳本都檢測DOM元素,大部分被檢查的元素都是誘餌和real ads。基于不同源碼的Anti-adblocker腳本的主要來源見表1。
作者提出兩種幫助廣告攔截器來抵制Anti-blocker的方法。
1.JavaScript Rewriting
它強(qiáng)制條件表達(dá)式取值,轉(zhuǎn)向執(zhí)行不存在廣告攔截器情況對應(yīng)的分支語句。在之前的有差異的執(zhí)行分析了解到,根據(jù)廣告攔截器軟件是否存在,anti腳本執(zhí)行不同的分支語句。因此作者的idea就是,強(qiáng)制改變條件判斷語句的值,轉(zhuǎn)到到?jīng)]有廣告攔截的語句分支執(zhí)行。這樣做可以有效避免任何反廣告攔截器的邏輯。
Rewriting只針對特定分支,而不是全部語句。一般都是條件判斷語句。有兩種方法來重寫一個(gè)分支中的條件:(1)用希望的輸出替換原來?xiàng)l件語句;(2)在條件語句末尾添加一個(gè)bool值,改變語句輸出。方法(1)禁止條件原來?xiàng)l件語句執(zhí)行,方法(2)不允許原來函數(shù)被調(diào)用。方法(1)不執(zhí)行原來方法,可能會影響其余代碼執(zhí)行。比如,一個(gè)變量是在該函數(shù)定義的,缺少后可能引發(fā)未定義變量導(dǎo)致的崩潰。方法(2)可以避免這個(gè)問題,論文傾向采用它。當(dāng)對齊a/b兩個(gè)執(zhí)行痕跡發(fā)現(xiàn)存在多重嵌套分支,決定重寫全部分支輸出或者部分,就變得非常重要了。論文傾向重寫外層條件,因?yàn)橹貙戄^低層可能會潛在引起功能崩潰。利用true讓條件語句為真,讓反廣告攔截軟件以為不存在攔截器,在外圍改變可避免內(nèi)部修改潛在問題。
JavaScript重寫方法對已知部署反廣告攔截器軟件并作出明顯回應(yīng)的網(wǎng)站測試,該系統(tǒng)成功規(guī)避了352(82.2%)。重寫后明顯沒有了警告和彈出消息。這種方法有一些缺點(diǎn)和局限性。首先它需要一個(gè)中間代理,不能作為瀏覽器擴(kuò)展立即應(yīng)用。其次它的介入容易引發(fā)網(wǎng)頁功能崩潰。
2.API Hooking
API Hooking主要是攔截應(yīng)用程序?qū)PI的調(diào)用,從而改變(擴(kuò)展)API的原有行為,常用代碼覆蓋來實(shí)現(xiàn)。作者注意到發(fā)布者調(diào)用API來檢測頁面狀態(tài),可以被瀏覽器擴(kuò)展截獲和修改,這使得可以進(jìn)行注入代碼來操作頁面對象。與檢測廣告攔截器有關(guān)的有兩種資源:DOM元素以及與元素不相干關(guān)的變量。通過注入腳本可以截獲取得的元素。如果對象被認(rèn)定是一個(gè)誘餌或者真實(shí)廣告,通過簡單返回一個(gè)偽造的對象。之后當(dāng)檢查對象尺寸,按照前期分析得到數(shù)據(jù)回復(fù)一個(gè)值就行。但是如果對象是動態(tài)生成,就很難確定是否是一個(gè)對象,需要運(yùn)行時(shí)更多監(jiān)視。如果檢測的變量與DOM元素?zé)o關(guān),唯一可能性就是與JavaScript攔截腳本有關(guān)。這種情況,有個(gè)全局變量定義在和廣告有關(guān)的腳本中。如果腳本被攔截,則變量成了未定義,因此引發(fā)廣告攔截器檢測(就是說,該腳本無效,說明ad-blocker存在并起作用)。幸運(yùn)的是如果變量是全局并直接訪問瀏覽器內(nèi)置window對象,可以用一條語句來攔截它,返回任何預(yù)期值(表示沒有adblocking)來通過檢測。如果是嵌套在其它對象中的變量,則不能攔截它的訪問。作為變通方法,作者提出讓與廣告相關(guān)的腳本加載,而不是攔截它,依賴其它廣告攔截規(guī)則刪除任何注入的廣告(畢竟廣告已經(jīng)插入DOM樹中)。如果與廣告相關(guān)腳本沒有注入任何廣告,只是提供誘餌定義了一些變量。不攔截他們,實(shí)際上已經(jīng)避免了Anti-blocker廣告攔截。
通過實(shí)施了一個(gè)概念性的Chrome擴(kuò)展,讓它工作在隨機(jī)選擇的網(wǎng)站子集(都是真實(shí)數(shù)據(jù)集;5個(gè)流行第三方JavaScript,5個(gè)用戶自行開發(fā)或不流行腳本,5個(gè)有明顯響應(yīng)),該方案工作非常好,抵御了所有網(wǎng)站。成功避免了anti-blocker,特別是總是成功避免了警告消息或者改變了報(bào)告消息。作者發(fā)現(xiàn)8個(gè)網(wǎng)站檢查DOM元素的屬性,7個(gè)網(wǎng)站檢查變量值。7個(gè)中,6個(gè)檢查全局變量。
API Hooking方法操縱DOM元素或者與被攔截的與ad相關(guān)的腳本。與JavaScript重寫相比,它將更精確,更少的副作用。
在論文結(jié)尾部分,作者從三個(gè)方面討論了當(dāng)前工作的局限性:
一是系統(tǒng)實(shí)施的不完整。不能覆蓋所有的分支,特別是潛在的分支操作;
二是有差別的執(zhí)行蹤跡分析系統(tǒng)魯棒性。網(wǎng)速和負(fù)載的波動會干擾系統(tǒng),甚至導(dǎo)致分析失敗;隨機(jī)性(行為隨機(jī)性和內(nèi)容隨機(jī)性)會影響系統(tǒng);
三是反廣告軟件規(guī)避的魯棒性。JavaScript rewriting 很難估計(jì)改變代碼帶來的影響,部署需要中間人代理,API hooking與JavaScript rewrite相比更準(zhǔn)確,帶來的副作用更小。