許 蕾, 劉蕊成, 陳貴美, 趙 晨, 張衛(wèi)豐
1(南京大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)系,江蘇 南京 210023)
2(南京郵電大學(xué) 計(jì)算機(jī)學(xué)院,江蘇 南京 210003)
目前,互聯(lián)網(wǎng)中最成熟的商業(yè)模式之一是以廣告為基礎(chǔ)的商業(yè)模式.據(jù)悉,谷歌公司 96%的收入都來自于網(wǎng)絡(luò)廣告.當(dāng)用戶使用搜索引擎時(shí),除了返回與查詢?cè)~相關(guān)的信息外,還會(huì)出現(xiàn)廣告,一旦用戶點(diǎn)擊了這些廣告,廣告的發(fā)布者需要付費(fèi)給搜索引擎,與此同時(shí),用戶有可能成為廣告商品的買家.這樣,在線廣告把商家、用戶、應(yīng)用開發(fā)者有機(jī)地聯(lián)系在一起,共同構(gòu)成了互聯(lián)網(wǎng)應(yīng)用的生態(tài)系統(tǒng).
為了便于發(fā)布、傳播廣告并提高用戶點(diǎn)擊率,廣告提供商通常使用JavaScript代碼動(dòng)態(tài)生成廣告頁(yè)面,并收集用戶交互、瀏覽器環(huán)境等信息.作為第三方代碼,這些廣告代碼可能給網(wǎng)站以及用戶帶來極大的安全隱患.例如,這類廣告代碼可以獲得用戶在瀏覽器上的行為,從而獲得用戶的訪問信息,增加了用戶隱私信息泄露的可能性,同時(shí)也打破了網(wǎng)站本身的完整性.更可怕的是,一些惡意廣告可能利用網(wǎng)頁(yè)中的漏洞,偷偷將惡意軟件安裝到用戶的電腦中.研究顯示,網(wǎng)絡(luò)上每天出現(xiàn)約 130萬(wàn)個(gè)惡意廣告,它們中的大部分都會(huì)下載惡意軟件并且進(jìn)行一定的偽裝,以繞過安全軟件的檢測(cè)[1-4].
現(xiàn)今大部分網(wǎng)站都使用JavaScript代碼動(dòng)態(tài)顯示信息.事實(shí)上,幾乎所有的惡意廣告都是通過JavaScript代碼加載的.因此,為了提高網(wǎng)頁(yè)的安全性,可以直接禁止所有JavaScript代碼的加載.但是由于包含JavaScript代碼的應(yīng)用十分普遍,網(wǎng)頁(yè)中幾乎所有的動(dòng)態(tài)效果和交互性強(qiáng)的顯示效果都需要使用JavaScript代碼,網(wǎng)站應(yīng)用越來越趨向于使用JavaScript代碼,以吸引用戶和增強(qiáng)表現(xiàn)力.因此,直接屏蔽JavaScript代碼會(huì)導(dǎo)致網(wǎng)頁(yè)的交互性降低,不能因噎廢食.
為了識(shí)別惡意廣告,需要追蹤廣告代碼調(diào)用路徑.但追蹤廣告代碼路徑具有很大的挑戰(zhàn),這是由于:(1) 網(wǎng)頁(yè)中混雜了大量HTML文件、JavaScript腳本文件、CSS文件,又由于有的腳本文件根本不執(zhí)行,很難識(shí)別出廣告相關(guān)的JavaScript文件;(2) JavaScript腳本文件中包含大量函數(shù),每個(gè)函數(shù)之間的調(diào)用關(guān)系錯(cuò)綜復(fù)雜,形成了很長(zhǎng)的函數(shù)調(diào)用鏈路,這些函數(shù)大都分布在不同的JavaScript文件中,也不容易識(shí)別函數(shù)的調(diào)用關(guān)系;(3) 為了保證用戶的瀏覽體驗(yàn)以及代碼本身的隱私和安全性,開發(fā)者往往對(duì)JavaScript代碼進(jìn)行了壓縮,使得整體的代碼可讀性變差,導(dǎo)致JavaScript代碼中函數(shù)調(diào)用鏈的獲取工作更加困難.
為此,我們計(jì)劃使用動(dòng)態(tài)分析方法獲取廣告的調(diào)用路徑.由于網(wǎng)頁(yè)廣告的調(diào)用過程實(shí)質(zhì)上是網(wǎng)站主通過廣告聯(lián)盟獲取廣告相關(guān)的 JavaScript代碼,因此我們的工作可以認(rèn)為是從廣告聯(lián)盟的代碼中獲取廣告調(diào)用路徑.本文的主要工作如下:(1) 對(duì)廣告相關(guān)的JavaScript腳本進(jìn)行分析,發(fā)現(xiàn)動(dòng)態(tài)廣告的生成特點(diǎn);(2) 根據(jù)生成特點(diǎn),使用動(dòng)態(tài)插樁工具對(duì)網(wǎng)頁(yè)進(jìn)行插樁,以獲得廣告的調(diào)用路徑;(3) 對(duì)iframe內(nèi)部調(diào)用路徑和跨iframe調(diào)用路徑進(jìn)行不同處理,獲得完整的調(diào)用路徑;(4) 通過實(shí)驗(yàn)分析以及與靜態(tài)分析方法的對(duì)比,說明本文方法的有效性:能夠在有限增加訪問時(shí)間(2~10X)的前提下,獲取到靜態(tài)方法無法獲取到的廣告動(dòng)態(tài)加載過程信息,并生成廣告代碼調(diào)用路徑.
本文第2節(jié)通過實(shí)例說明廣告調(diào)用路徑獲取的困難性.第3節(jié)設(shè)定規(guī)則使用動(dòng)態(tài)插樁工具對(duì)廣告相關(guān)的調(diào)用路徑進(jìn)行追蹤.第4節(jié)分別介紹對(duì)調(diào)用路徑中iframe內(nèi)部和跨iframe調(diào)用路徑的獲取.第5節(jié)是實(shí)驗(yàn)部分,針對(duì) 21個(gè)真實(shí)網(wǎng)站進(jìn)行廣告代碼調(diào)用路徑的追蹤并給出具體的統(tǒng)計(jì)結(jié)果.另外,還與靜態(tài)分析方法進(jìn)行了對(duì)比,說明本文方法的有效性.第6節(jié)為相關(guān)工作,包括互聯(lián)網(wǎng)廣告研究和JavaScript程序分析.第7節(jié)總結(jié)全文并指出后續(xù)可開展的工作.
網(wǎng)頁(yè)中動(dòng)態(tài)廣告的加載和生成是一個(gè)復(fù)雜的過程,其傳播路徑可能涉及多個(gè)JavaScript腳本文件.本節(jié)我們用一個(gè)示例描述網(wǎng)頁(yè)中動(dòng)態(tài)廣告的加載過程,并說明廣告調(diào)用路徑獲取的困難所在.
以www.gamefaqs.com為例,圖1虛線以上區(qū)域展示了該網(wǎng)站主頁(yè)加載完畢后的代碼及截圖,紅色橢圓區(qū)域是由Google提供的動(dòng)態(tài)廣告;虛線以下區(qū)域顯示廣告加載的動(dòng)態(tài)過程,包括多個(gè)JS文件的調(diào)用.在該應(yīng)用中,為了個(gè)性化推送廣告和躲避檢測(cè),源代碼經(jīng)過了一些混淆處理.為了方便閱讀,圖中所示代碼已經(jīng)進(jìn)行了一些簡(jiǎn)化處理.其廣告加載的詳細(xì)步驟描述如下.
(1) 瀏覽器加載主頁(yè),加載后由服務(wù)器返回的代碼如圖1中虛線以下區(qū)域的左半部分第1行~第20行所示.當(dāng)?shù)?行~第14行中的腳本語(yǔ)言執(zhí)行后,一個(gè)新script標(biāo)簽及其包含的JS文件會(huì)加載到頁(yè)面中(ads.js).
(2) 瀏覽器解析新增加的script標(biāo)簽并執(zhí)行來自pubads.g.doubleclick.net中的ads.js文件.該文件第4行又向頁(yè)面中插入新的script標(biāo)簽并執(zhí)行JS文件akyi97Q8.js.
(3) 瀏覽器加載來自tpc.googlesyndication.com中的akyi97Q8.js文件,該文件創(chuàng)建了一個(gè)iframe標(biāo)簽(文件中第 1行),并在第 3行中引用 tpc.googlesyndication.com的 adXpYxnS.html文件,并把該 iframe嵌套到 id為google_ads_iframe的div下(第6行、第7行).
(4) 瀏覽器從tpc.googlesyndication.com加載adXpYxnS.html文件.該HTML文件觸發(fā)了廣告內(nèi)容相關(guān)函數(shù)的執(zhí)行,該函數(shù)返回廣告相關(guān)的內(nèi)容(pagead2.googlesyndication.com).
(5) 最終,瀏覽器加載并顯示實(shí)際的廣告.頁(yè)面截圖和加載完畢后的源代碼如圖1中虛線上部所示.
從圖1所示例子可以看出,網(wǎng)頁(yè)中廣告相關(guān)的JavaScript調(diào)用路徑難以獲得有以下幾個(gè)原因.
(1) 由于網(wǎng)頁(yè)中混雜著大量的HTML代碼、JavaScript腳本文件、CSS文件,又由于有的腳本文件根本不執(zhí)行,這給廣告相關(guān)JavaScript文件的識(shí)別工作帶來了相當(dāng)大的困難.
例如,網(wǎng)站www.gamefaqs.com中的measure.js存在于網(wǎng)頁(yè)中,卻沒有被執(zhí)行,也難以判斷該JS文件是否是廣告相關(guān)代碼.
(2) JavaScript腳本文件中包含大量函數(shù),包括匿名函數(shù),各函數(shù)之間的調(diào)用關(guān)系錯(cuò)綜復(fù)雜,形成了很長(zhǎng)的函數(shù)調(diào)用路徑.這些函數(shù)大都分布在不同的JavaScript文件中,這對(duì)觀察和識(shí)別函數(shù)的調(diào)用關(guān)系造成了不便.
例如,圖1中存在的文件調(diào)用路徑為ads.js?akyi97Q8.js?adXpYxnS.html,同時(shí)還有眾多其他文件沒有顯示出來,要從中找出這些調(diào)用路徑難度很大.
(3) 另外,為了保證用戶的瀏覽體驗(yàn)以及代碼本身的隱私和安全性,HTML頁(yè)面中的JavaScript代碼通常會(huì)被壓縮或混淆,使得整體的代碼可讀性變差,導(dǎo)致JavaScript文件中函數(shù)調(diào)用鏈的獲取工作更加困難重重.
例如,圖 1所示 www.gamefaqs.com網(wǎng)站的 ads.js文件包含豐富的信息,實(shí)際找到的文件卻只有1行代碼,但卻有上千列.這些代碼壓縮或混淆在一起,可讀性極差,也進(jìn)一步增加了調(diào)用路徑獲取的難度.
本節(jié)我們通過使用動(dòng)態(tài)插樁工具Jalangi對(duì)包含JavaScript代碼的網(wǎng)頁(yè)進(jìn)行插樁,并針對(duì)JavaScript函數(shù)進(jìn)行若干特殊處理,以獲取廣告的調(diào)用路徑.
Jalangi[5]是美國(guó)加州大學(xué)伯克利分校在 2013年開發(fā)實(shí)現(xiàn)的 JavaScript動(dòng)態(tài)分析框架,能夠?qū)η岸撕秃蠖薐avaScript進(jìn)行動(dòng)態(tài)分析,允許監(jiān)控每個(gè)JavaScript程序的操作以及編寫自己的程序分析代碼;通過記錄-回放的機(jī)制來實(shí)現(xiàn)JavaScript代碼的插樁,并通過影子執(zhí)行的方法運(yùn)行自定義的動(dòng)態(tài)分析腳本.Jalangi提供了豐富的分析API,以實(shí)現(xiàn)各種動(dòng)態(tài)程序分析.當(dāng)使用Jalangi對(duì)網(wǎng)頁(yè)進(jìn)行分析時(shí),瀏覽器通過使用一個(gè)代理服務(wù)器向網(wǎng)頁(yè)所在服務(wù)器發(fā)送請(qǐng)求,并獲得整個(gè)原始頁(yè)面的JavaScript腳本文件;接著,Jalangi對(duì)獲得的腳本文件進(jìn)行插樁.
Jalangi在網(wǎng)頁(yè)加載前對(duì)原始代碼進(jìn)行插樁,并生成插樁后代碼.
插樁后代碼調(diào)用了兩個(gè) Jalangi回調(diào)函數(shù) J$.W和 J$.R,分別是變量賦值和變量讀取的分析回調(diào)函數(shù),變量名和變量值等參數(shù)會(huì)被傳遞給這兩個(gè)函數(shù).J$.R(5,‘b’,b)表示讀取名稱為‘b’的變量,其中數(shù)字 5表示回調(diào)函數(shù)的標(biāo)識(shí)符;J$.W(9,‘a(chǎn)’,J$.R(5,‘b’,b),a)表示對(duì)變量名為‘a(chǎn)’的變量賦值為 J$.R(5,‘b’,b)的返回值,其中數(shù)字 9 也表示回調(diào)函數(shù)的標(biāo)識(shí)符.此時(shí)在瀏覽器中加載網(wǎng)頁(yè),會(huì)執(zhí)行插樁后的JavaScript代碼,且不會(huì)破壞頁(yè)面的原有設(shè)置.
另外,還可以通過在工具Jalangi源程序中設(shè)定一系列規(guī)則,對(duì)JavaScript代碼進(jìn)行動(dòng)態(tài)插樁,進(jìn)而得到執(zhí)行軌跡、變量取值等定制化信息.因此,我們可以設(shè)定規(guī)則對(duì)網(wǎng)頁(yè)進(jìn)行插樁,以獲取廣告相關(guān)的JavaScript腳本.
Jalangi提供了回調(diào)函數(shù)invokeFunPre和putFieldPre,它們分別在函數(shù)執(zhí)行前和在對(duì)象屬性賦值前進(jìn)行分析操作.其中,invokeFunPre函數(shù)包含幾個(gè)重要的參數(shù):(1) iid,當(dāng)前回調(diào)函數(shù)執(zhí)行時(shí)的唯一標(biāo)識(shí)符,以數(shù)字類型表示;(2) f,指向當(dāng)前函數(shù)對(duì)象;(3) base,如果函數(shù)f是某個(gè)對(duì)象的方法,則base是該對(duì)象的引用,否則為null;(4) args,函數(shù) f的參數(shù)列表,以數(shù)組形式表示;(5) isConstructor,判斷函數(shù) f是否為構(gòu)造函數(shù),以布爾形式類型表示.putFieldPre函數(shù)包含幾個(gè)重要的參數(shù):(1) iid,當(dāng)前回調(diào)函數(shù)執(zhí)行時(shí)的唯一標(biāo)識(shí)符,以數(shù)字類型表示;(2) base,賦值的屬性隸屬的對(duì)象;(3) offset,屬性名;(4) val,在base[offset]中存儲(chǔ)的值,即該對(duì)象屬性存儲(chǔ)的原始值.
由于時(shí)間、精力有限,我們只追蹤來自百度和谷歌的廣告調(diào)用路徑,且對(duì)于域名與當(dāng)前網(wǎng)頁(yè)所在服務(wù)器的二級(jí)域名不相同時(shí)才進(jìn)行追蹤,以下定義均建立在此前提之上.另外,根據(jù)同源策略,當(dāng) iframe引用的URL與當(dāng)前網(wǎng)頁(yè)的域名不同時(shí),DOM元素是不可以被iframe所在頁(yè)面內(nèi)的JavaScript代碼操作的,所以document內(nèi)部的函數(shù)調(diào)用是指在一個(gè)iframe內(nèi)的函數(shù)調(diào)用.
定義1.document內(nèi)廣告路徑的開始節(jié)點(diǎn)S若函數(shù)調(diào)用時(shí)沒有調(diào)用者或者調(diào)用者是DOM事件處理函數(shù),則認(rèn)為是廣告路徑的開始節(jié)點(diǎn).另外,我們使用unname作為匿名函數(shù)調(diào)用的標(biāo)識(shí).
例如:圖1中左側(cè)代碼片段的開始節(jié)點(diǎn)為第3行~第15行的匿名函數(shù).
定義2.document內(nèi)廣告路徑的結(jié)束節(jié)點(diǎn)E若使用函數(shù)appendChild、insertBefore以及document.write插入〈img〉、〈script〉、〈a〉、〈iframe〉標(biāo)簽,或使用 innerHTML 方式插入〈iframe〉標(biāo)簽,則將其作為廣告路徑的結(jié)束節(jié)點(diǎn).
例如,圖 1右側(cè)底部 ads.js文件中的結(jié)束節(jié)點(diǎn)為第 6行用 insertBefore方式插入代碼片段,圖 1右側(cè)中部akyi97Q8.js文件中的結(jié)束節(jié)點(diǎn)為第7行用appendChild方式插入的〈iframe〉標(biāo)簽.
定義3.document內(nèi)廣告路徑的中間節(jié)點(diǎn)M開始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)之間的一系列函數(shù)調(diào)用均作為中間節(jié)點(diǎn).
例如,圖1虛線下方左側(cè)廣告調(diào)用路徑為%source%unnamed→insertBeforescriptads.js,虛線下部右側(cè)底部廣告調(diào)用路徑為%source%unnamed→insertBeforescriptakyi97Q8.js,虛線下部右側(cè)上部廣告調(diào)用路徑為%source%unnamed→appendChildiframe.
虛線下部代碼片段組成一條 document內(nèi)部的函數(shù)調(diào)用路徑,即%source%unnamed→insertBeforescriptads.js→%source%unnamed→insertBeforescriptakyi97Q8.js→%source%unnamed→appendChildiframe.
另外,我們注意到,JavaScript函數(shù)中使用setTimeout和setInterval設(shè)置了定時(shí)執(zhí)行函數(shù),函數(shù)執(zhí)行時(shí)調(diào)用者會(huì)變?yōu)闉g覽器.因此,為了廣告鏈路的完整性,我們需要將調(diào)用 setTimeout和 setInterval的函數(shù)作為定時(shí)執(zhí)行函數(shù)的父節(jié)點(diǎn).
定義5.跨document的函數(shù)調(diào)用路徑AP記為P1…Pm,其中,Pi表示第i個(gè)document內(nèi)部的廣告路徑,相鄰節(jié)點(diǎn)Pi,Pi+1表示Pi結(jié)束節(jié)點(diǎn)產(chǎn)生了第i+1個(gè)document.
例如:在圖1虛線下右側(cè)中部中使用appendchild插入一個(gè)iframe,iframe的 src為 adXpYxnS.html,即這個(gè)document產(chǎn)生了另一個(gè)內(nèi)容為adXpYxnS.html的document.
我們考慮使用Jalangi對(duì)網(wǎng)頁(yè)進(jìn)行動(dòng)態(tài)插樁,以獲得廣告的調(diào)用路徑,具體方案如圖2所示,其主要的工作流程是:在瀏覽器中設(shè)置代理,當(dāng)我們?cè)L問一個(gè)網(wǎng)頁(yè)時(shí),代理服務(wù)器會(huì)獲取從Web服務(wù)器返回的HTML網(wǎng)頁(yè)文件及其引用的JS腳本文件,并調(diào)用Jalangi對(duì)HTML和JS文件中的JavaScript腳本代碼進(jìn)行插樁,然后記錄執(zhí)行軌跡并在瀏覽器上顯示頁(yè)面內(nèi)容.
每執(zhí)行一行 JavaScript腳本代碼,其執(zhí)行軌跡均會(huì)被記錄下來,通過分析將其關(guān)聯(lián)起來,就可以追蹤特定代碼的調(diào)用路徑.一個(gè)函數(shù)調(diào)用路徑是一個(gè)函數(shù)調(diào)用的相關(guān)信息項(xiàng)的序列,每一項(xiàng)都包含:執(zhí)行的函數(shù);函數(shù)調(diào)用在代碼中的位置,以行列數(shù)表示;函數(shù)調(diào)用所在的js文件的url.函數(shù)調(diào)用路徑中相鄰的兩項(xiàng)表示前一項(xiàng)中的函數(shù)調(diào)用了后一項(xiàng)中的函數(shù).本文獲取函數(shù)調(diào)用路徑的方法是基于函數(shù)的參數(shù)對(duì)象arguments實(shí)現(xiàn).一個(gè)函數(shù)的參數(shù)對(duì)象可以在該函數(shù)的作用域內(nèi)被訪問,也可以在這個(gè)函數(shù)直接調(diào)用的函數(shù)的作用域內(nèi)被訪問.參數(shù)對(duì)象是一個(gè)類數(shù)組對(duì)象,存放著包括本次函數(shù)調(diào)用傳入的實(shí)參arguments[0]~arguments[arguments.length-1]和對(duì)該函數(shù)的引用arguments.callee.
我們通過改寫Jalangi的invokeFunPre分析回調(diào)函數(shù),在被分析代碼中的函數(shù)調(diào)用之前,將函數(shù)調(diào)用路徑作為一個(gè)額外的實(shí)參傳遞給它,則函數(shù)執(zhí)行后該函數(shù)調(diào)用路徑會(huì)出現(xiàn)在它的參數(shù)對(duì)象里;在其調(diào)用的任何函數(shù)作用域內(nèi),都可以通過arguments.callee.caller.arguments訪問到前者的參數(shù)對(duì)象存放的函數(shù)調(diào)用路徑.
一個(gè)函數(shù)對(duì)應(yīng)的函數(shù)調(diào)用路徑即以該次函數(shù)調(diào)用為終點(diǎn)的一系列函數(shù)調(diào)用.Jalangi將原代碼中的函數(shù)調(diào)用替換成一個(gè)包裝函數(shù)的調(diào)用,該包裝函數(shù)先調(diào)用 invokeFunPre進(jìn)行調(diào)用前分析,再調(diào)用原代碼中的函數(shù)的插樁后版本,最后調(diào)用 invokeFun進(jìn)行調(diào)用后分析.原本傳遞給原函數(shù)的參數(shù)現(xiàn)在傳遞給包裝函數(shù),且該包裝函數(shù)的調(diào)用者與原函數(shù)在插樁前原本的調(diào)用者是一致的;因?yàn)镴alangi將包裝函數(shù)的參數(shù)對(duì)象傳遞給invokeFunPre,所以我們可以獲取到包裝函數(shù)的調(diào)用函數(shù)的參數(shù)對(duì)象,提取后者對(duì)應(yīng)的函數(shù)調(diào)用路徑.與此同時(shí),我們也可以通過invokeFunPre在一個(gè)函數(shù)的參數(shù)對(duì)象里初始化一個(gè)函數(shù)調(diào)用路徑.
為了捕捉廣告調(diào)用路徑的開始、過程和結(jié)束,我們?cè)O(shè)定一條廣告路徑由0或一串函數(shù)調(diào)用路徑和一次插入某些特定 DOM 元素的操作組成.一個(gè)完整的網(wǎng)頁(yè)廣告生成流程包含不少于一個(gè)的廣告路徑.經(jīng)過調(diào)研我們發(fā)現(xiàn),廣告調(diào)用路徑涉及JavaScript中3類原生函數(shù),對(duì)應(yīng)于定義2,即:使用insertBefore或appendChild插入script、a、img、iframe標(biāo)簽;使用document.write插入script、a、img、iframe標(biāo)簽;使用innerHTML插入iframe標(biāo)簽.另外,對(duì)于setTimeout和setInterval的處理,也需要特殊對(duì)待.
綜合大量文獻(xiàn)發(fā)現(xiàn),溶血現(xiàn)象影響生化檢測(cè)項(xiàng)目主要表現(xiàn)在以下幾點(diǎn):①對(duì)肝功能指標(biāo)影響:研究報(bào)道,溶血現(xiàn)象對(duì)谷草轉(zhuǎn)氨酶、谷丙轉(zhuǎn)氨酶、總蛋白和白蛋白等檢測(cè)項(xiàng)目帶來正干擾,而對(duì)直接膽紅素和總膽紅素帶來負(fù)干擾[4];②對(duì)腎功能指標(biāo)影響:文獻(xiàn)報(bào)道,溶血現(xiàn)象對(duì)腎功能檢測(cè)項(xiàng)目帶來的影響比對(duì)肝功能帶來的影響要小,因?yàn)槿苎蟮墓入赘孰牡燃t細(xì)胞物質(zhì)可吸收尿酸中的H2 O2;③對(duì)血脂血糖指標(biāo)的影響:目前臨床上檢驗(yàn)血糖的方法主要為葡萄糖氧化酶聯(lián)合H2 O2酶法,但血液樣本溶血后產(chǎn)生的血紅蛋白會(huì)不同程度的影響血糖檢測(cè)過程中的反應(yīng)物,從而使得檢測(cè)結(jié)果出現(xiàn)誤差。
為了在函數(shù)調(diào)用過程中記錄并傳遞執(zhí)行軌跡(trace)信息,我們需要通過invokeFunPre中特定的函數(shù)參數(shù)記錄并追蹤trace.為此,我們?cè)O(shè)置了特定的trace信息結(jié)構(gòu).
如圖3所示,trace中記錄的document內(nèi)廣告調(diào)用路徑P的信息結(jié)構(gòu)為
%source%函數(shù)名稱,位置,文件名,函數(shù)調(diào)用的位置||(函數(shù)名稱,位置,文件名,函數(shù)調(diào)用的位置||)*插入元素的方式,插入的內(nèi)容,插入內(nèi)容的src,位置,文件名,函數(shù)調(diào)用的位置
其中,“%source%”表示廣告路徑P的開始節(jié)點(diǎn)S;“||”作為每次函數(shù)調(diào)用的分隔標(biāo)識(shí);“(函數(shù)名稱,位置,文件名||)*”表示0個(gè)或多個(gè)中間節(jié)點(diǎn)M;“插入元素的方式”表示結(jié)束節(jié)點(diǎn)的開始,包括了insertBefore、appendChild、document.write這3種方式.整個(gè)廣告調(diào)用路徑包括1個(gè)開始節(jié)點(diǎn)、0個(gè)或多個(gè)中間節(jié)點(diǎn)、1個(gè)結(jié)束節(jié)點(diǎn).
由此構(gòu)成document內(nèi)的廣告調(diào)用路徑集合CS和所有document的廣告調(diào)用路徑集合CSS:CS的信息結(jié)構(gòu)為keyvalue鍵值對(duì),key為文件名,每個(gè)value為一個(gè)二維數(shù)組,第1維表示trace,第2維表示trace的每一項(xiàng)的具體信息;CSS的信息結(jié)構(gòu)為(url,P)*,其中,url表示當(dāng)前document所在的url,P表示當(dāng)前document廣告調(diào)用路徑.
為了得到以上信息,我們需要在冗長(zhǎng)、復(fù)雜、可能包含混淆代碼的JavaScript文件中識(shí)別出廣告相關(guān)的函數(shù),并確定調(diào)用路徑的起始點(diǎn)、更新以及終止點(diǎn),具體處理過程如下所示.
3.4.1 廣告相關(guān)函數(shù)調(diào)用路徑初始化
需要說明的是,在引入的第三方腳本中,如果一個(gè)函數(shù)被網(wǎng)站服務(wù)商提供的腳本代碼調(diào)用,則這次函數(shù)調(diào)用不被認(rèn)為有關(guān)廣告生成,而是第三方函數(shù)庫(kù)的調(diào)用行為,因?yàn)楝F(xiàn)今主流的廣告聯(lián)盟不要求網(wǎng)站開發(fā)者調(diào)用它們的接口以生成廣告.
圖 4是一個(gè)簡(jiǎn)單的廣告調(diào)用路徑代碼示例:當(dāng)用戶訪問網(wǎng)站www.A.com的主頁(yè)時(shí),頁(yè)面主動(dòng)加載了C.js文件,這段代碼來自于ads.B.com,即對(duì)于主頁(yè)面來說,這段代碼來自于第三方JavaScript庫(kù).因此,符合我們?cè)O(shè)定的廣告調(diào)用路徑起始點(diǎn)(滿足條件2).經(jīng)過Jalangi插樁,可以記錄下trace:onload→A.
3.4.2 廣告相關(guān)的函數(shù)調(diào)用路徑更新
如果一個(gè)函數(shù)有調(diào)用者且調(diào)用者的參數(shù)對(duì)象中存在函數(shù)調(diào)用路徑,則說明它已被標(biāo)記為潛在廣告路徑的一部分,所以我們可以將它的函數(shù)調(diào)用路徑和當(dāng)前的函數(shù)調(diào)用相關(guān)信息拼接,形成更新后的函數(shù)調(diào)用路徑.
對(duì)于函數(shù)調(diào)用路徑更新,有一個(gè)特殊的情況是:當(dāng)一個(gè)函數(shù)調(diào)用setTimeout延時(shí)執(zhí)行或調(diào)用setInterval定時(shí)延時(shí)另一個(gè)函數(shù)時(shí),從后者的參數(shù)對(duì)象中獲取的調(diào)用者是 null,即從調(diào)用棧的角度來看,兩者沒有直接調(diào)用的關(guān)系.但是在調(diào)研中,我們發(fā)現(xiàn):廣告腳本中有很多地方使用了這種定時(shí)或延時(shí)執(zhí)行函數(shù).因此,需要捕獲這樣的調(diào)用關(guān)系.
如圖5所示,在加載執(zhí)行A函數(shù)時(shí),使用setInterval每隔5s調(diào)用B函數(shù),在B函數(shù)中調(diào)用了C函數(shù),C函數(shù)又做了一些操作.因此,函數(shù)的調(diào)用路徑是A→setInterval→B→C.但是由于setInterval設(shè)置的延時(shí),使得調(diào)用路徑在B之后發(fā)生中斷,導(dǎo)致無法獲取到C函數(shù)的調(diào)用信息.setTimeout的情況與此類似.
因此,使用 setTimeout或 setInterval函數(shù)阻斷了廣告調(diào)用路徑的傳播,需要對(duì)這兩個(gè)函數(shù)進(jìn)行特殊處理.處理方法是:創(chuàng)建一個(gè)閉包,該閉包內(nèi)存放著setTimeout函數(shù)或setInterval函數(shù)調(diào)用者參數(shù)對(duì)象的引用、要延時(shí)或定時(shí)執(zhí)行的目標(biāo)函數(shù),其中,延時(shí)或定時(shí)執(zhí)行的對(duì)象不再是原目標(biāo)函數(shù),而是這個(gè)閉包,這個(gè)閉包在運(yùn)行時(shí)會(huì)先將setTimeout函數(shù)或setInterval函數(shù)調(diào)用者的參數(shù)對(duì)象傳遞給分析函數(shù)invokeFunPre,然后再執(zhí)行目標(biāo)函數(shù).圖6展示了創(chuàng)建閉包的函數(shù)關(guān)鍵代碼,其中,J$.invokeFun函數(shù)會(huì)調(diào)用分析函數(shù) invokeFunPre,并調(diào)用目標(biāo)函數(shù)fun;args里只有setTimeout函數(shù)或setInterval函數(shù)調(diào)用者的參數(shù)對(duì)象,但它不作為目標(biāo)函數(shù)真正的參數(shù)對(duì)象.
經(jīng)過上述處理,在分析延時(shí)和定時(shí)的函數(shù)調(diào)用時(shí),就可以獲取到存放在設(shè)置延時(shí)和定時(shí)執(zhí)行的函數(shù)的參數(shù)對(duì)象中的函數(shù)調(diào)用路徑,所以能夠捕獲非直接的調(diào)用關(guān)系.仍然使用圖4所示的例子,可以看到,A函數(shù)在調(diào)用B函數(shù)時(shí)使用setTimeout等待了5 000ms,這個(gè)操作會(huì)影響廣告路徑的延續(xù),因此Jalangi在這里對(duì)setTimeout進(jìn)行特殊處理,即調(diào)用invokeFun函數(shù)直接執(zhí)行B,以此對(duì)路徑進(jìn)行延續(xù),這樣獲得的trace路徑為onload→A→B,沒有丟失對(duì)B函數(shù)的調(diào)用.
3.4.3 廣告相關(guān)的函數(shù)調(diào)用路徑完成
廣告調(diào)用路徑可能會(huì)包含多次頁(yè)面跳轉(zhuǎn)(從一個(gè)JS文件鏈接到另一個(gè)JS文件),但最終會(huì)需要將包含廣告內(nèi)容的頁(yè)面通過DOM操作插入到已有的HTML頁(yè)面中,插入元素的類型可能是腳本元素〈script〉、內(nèi)聯(lián)框架元素〈iframe〉、超鏈接元素〈a〉以及圖片元素〈img〉,這是因?yàn)榫W(wǎng)頁(yè)廣告的生成包括以下幾種情況.
1) 廣告有可能通過插入〈script〉腳本來加載外部源的JS腳本文件;
2) 插入〈a〉標(biāo)簽或〈img〉標(biāo)簽,由于很多網(wǎng)絡(luò)廣告通過插入一段鏈接指向某個(gè)真正廣告內(nèi)容的 url地址,所以需要進(jìn)行標(biāo)記;插入〈img〉標(biāo)簽則為插入圖片,這時(shí)往往也是廣告生成的最后一步,即用圖片展示廣告內(nèi)容,且可以起到與〈a〉標(biāo)簽一樣的作用,因此也需要進(jìn)行標(biāo)記;
3) 插入〈iframe〉標(biāo)簽,由于網(wǎng)頁(yè)上的廣告位通常為一個(gè)既定的區(qū)域,且保證不受頁(yè)面上其他腳本的DOM操作帶來的影響,常用一個(gè)iframe引入一個(gè)廣告頁(yè)面.
另外,一個(gè)廣告腳本可能會(huì)插入其他廣告腳本,也可能會(huì)插入iframe顯示廣告頁(yè)面,而且〈a〉和〈img〉元素都可以通過設(shè)置src屬性實(shí)現(xiàn)廣告鏈接.
使用 JavaScript語(yǔ)言在頁(yè)面 DOM 結(jié)構(gòu)中插入 HTML元素的方法有以下幾種:調(diào)用 DOM 元素對(duì)象的insertBefore和appendChild方法、調(diào)用document.write函數(shù)和賦值DOM元素對(duì)象的innerHTML屬性.
1) 對(duì)insertBefore和appendChild函數(shù)的分析
對(duì)于使用insertBefore和appendChild函數(shù)插入iframe、script、a、img標(biāo)簽的情況,我們認(rèn)為該條路徑已經(jīng)到達(dá)了終止點(diǎn),此時(shí)需要判斷其 caller的情況,如果有 caller屬性,即有調(diào)用者,而且其調(diào)用者不是事件處理函數(shù),則對(duì)該條路徑進(jìn)行輸出;如果iframe、script、a標(biāo)簽沒有調(diào)用者,或者調(diào)用者就是事件處理函數(shù),則對(duì)整條廣告?zhèn)鞑ヂ窂竭M(jìn)行輸出.
在圖4中,B函數(shù)創(chuàng)建了一個(gè)script,然后用appendChild方法添加到網(wǎng)頁(yè)中.由于B函數(shù)的調(diào)用者A函數(shù)的參數(shù)中已經(jīng)添加過trace屬性,即A和B都在廣告調(diào)用路徑上,因此為B函數(shù)也添加調(diào)用路徑的屬性:onload→A→B→insertscript.appendChild.這就表示了該文件內(nèi)廣告調(diào)用的結(jié)束,因此在控制臺(tái)對(duì)B函數(shù)所綁定的參數(shù)進(jìn)行打印輸出.
2) 對(duì)document.write函數(shù)的分析
考慮到document.write函數(shù)接收的參數(shù)是字符串而非DOM元素對(duì)象,滿足HTML表達(dá)式規(guī)范的字符串會(huì)被解析為DOM對(duì)象,所以我們對(duì)document.write的參數(shù)進(jìn)行字符串匹配,確定它是否插入了之前提到的4類元素.同樣,我們也要判斷寫入的script標(biāo)簽有沒有src屬性.圖7所示例子說明了通過document.write插入元素的過程:第7行在A.js中使用document.write嵌入一個(gè)script標(biāo)簽,script標(biāo)簽執(zhí)行B.js.
3) 對(duì)innerHTML屬性的分析
向一個(gè)DOM元素的innerHTML屬性賦值一個(gè)合法的HTML表達(dá)式字符串,可以在其下面插入元素.使用Jalangi的putFieldPre分析回調(diào)函數(shù),可以分析任意對(duì)象屬性的寫入行為.當(dāng)寫入一個(gè)對(duì)象的屬性時(shí),判斷對(duì)象是否為DOM元素對(duì)象以及屬性名是否為innerHTML,且寫入了與廣告相關(guān)的標(biāo)簽.
最后需要將函數(shù)調(diào)用路徑和DOM操作關(guān)聯(lián)起來,組成單條廣告路徑.在使用appendChild、insertBefore和document.write函數(shù)來插入廣告相關(guān)元素時(shí),如果它們有調(diào)用者,則可以獲取它們的調(diào)用者參數(shù)對(duì)象里的函數(shù)調(diào)用路徑,并附上當(dāng)前DOM操作的相關(guān)信息作為最后一項(xiàng);而對(duì)于DOM元素對(duì)象的innerHTML屬性的寫入,我們擴(kuò)展了Jalangi的代碼,使putFieldPre函數(shù)接收一個(gè)額外的參數(shù),即該條屬性賦值語(yǔ)句所在的函數(shù),從這個(gè)函數(shù)的參數(shù)對(duì)象里尋找函數(shù)調(diào)用路徑并拼接上該DOM操作的相關(guān)信息,作為最后一項(xiàng).
動(dòng)態(tài)生成的廣告能夠在網(wǎng)頁(yè)廣告位中顯示來自于第三方廣告聯(lián)盟的廣告資源,這些廣告資源可能是圖片、視頻,甚至是一個(gè)URL鏈接.而根據(jù)JavaScript的同源策略,iframe引用的URL屬于不同域名網(wǎng)頁(yè)內(nèi)的DOM是不可以被 iframe所在頁(yè)面內(nèi)的 JavaScript代碼操作的,所以,為了不影響正常顯示,這些來自于第三方的圖片、視頻資源等,一般都嵌套在 iframe里,再放入網(wǎng)頁(yè)中.一個(gè)頁(yè)面和它的 iframe引用的頁(yè)面各自具有以 document節(jié)點(diǎn)為根節(jié)點(diǎn)的DOM樹.
在一個(gè) document內(nèi),我們規(guī)定在兩條廣告路徑中,如果其中一條插入了一個(gè)〈script〉標(biāo)簽,引用了某個(gè) JS文件,而另一條的第1項(xiàng)對(duì)應(yīng)的語(yǔ)句在該JS文件中,則兩者是關(guān)聯(lián)的,前者是后者的前繼.我們將獲取到的所有路徑都放在一個(gè)路徑集合中,方便之后獲取到新的廣告路徑時(shí)通過算法回溯它的所有前繼.
document內(nèi)的廣告路徑回溯算法如算法1所示.該算法接受document內(nèi)所有廣告路徑集合CS和需要回溯的路徑P,遍歷CS中的路徑,若找到一條插入script腳本且P對(duì)應(yīng)的語(yǔ)句處于該腳本中,則遞歸回溯該條路徑的前繼,直到回溯完畢.
算法1.document內(nèi)廣告路徑回溯算法.
在某些情況下,一個(gè)頁(yè)面插入的 iframe引用的頁(yè)面里又會(huì)出現(xiàn)其他廣告相關(guān)元素的動(dòng)態(tài)插入,我們將這些行為關(guān)聯(lián)在一起.在兩條廣告路徑中,如果其中一條路徑插入了一個(gè)iframe,另一條廣告路徑起源于該iframe引用的網(wǎng)頁(yè)中,則前者是后者的前繼.
每條廣告路徑都對(duì)應(yīng)一個(gè) document,即它的每一項(xiàng)對(duì)應(yīng)的文件都是被該 document引用的.如算法 2所示,為了關(guān)聯(lián)跨documents的廣告路徑,遍歷其他document的廣告路徑集合里的路徑,并查看這些路徑的尾部是否插入了一個(gè)iframe且src屬性是否是被回溯路徑對(duì)應(yīng)的document的url.如果存在這樣的路徑,則該路徑是這個(gè)待回溯路徑的前繼.與此同時(shí),一個(gè)document對(duì)應(yīng)的所有廣告路徑都與插入該document的路徑相關(guān)聯(lián).
算法2.跨documents廣告路徑回溯算法.
在圖8的示例中,A函數(shù)創(chuàng)建了一個(gè)iframe,用appendChild插入一個(gè)iframe標(biāo)簽,作為廣告調(diào)用路徑的終止點(diǎn).此時(shí)得到的廣告調(diào)用路徑為A→appendChild(ifr).在iframe內(nèi)部又調(diào)用了B函數(shù),B函數(shù)又調(diào)用了C函數(shù),C函數(shù)插入一個(gè)圖片,使用appendChild插入img標(biāo)簽,此時(shí),這部分的廣告調(diào)用路徑結(jié)束,這部分的廣告調(diào)用路徑為appendChild(ifr)→B→C→appendChild(img).
通過使用算法3,可以將圖8所示的跨iframe的兩條廣告調(diào)用路徑進(jìn)行拼接,從而獲得該廣告的完整調(diào)用路徑: A→appendChild(ifr)→B→C→appendChild(img).
算法3.獲取廣告調(diào)用路徑中涉及的JS文件url.
本節(jié)我們通過實(shí)驗(yàn)來展示使用動(dòng)態(tài)插樁方法獲得廣告代碼調(diào)用路徑,通過對(duì)比實(shí)驗(yàn)來驗(yàn)證本文方法的優(yōu)越性.
為了說明本文方法的有效性,我們對(duì)動(dòng)態(tài)插樁工具Jalangi進(jìn)行了擴(kuò)展并開展了以下實(shí)驗(yàn),以期動(dòng)態(tài)追蹤廣告代碼調(diào)用路徑并獲取到調(diào)用路徑長(zhǎng)度、廣告插入方式等特征信息,然后具體分析廣告相關(guān)的JavaScript腳本文件中原生函數(shù)insertBefore、appendChild、document.wirte、innerHTML所占的比重,從而更加明確廣告代碼的加載、傳播方式.另外,還與靜態(tài)分析方式進(jìn)行了對(duì)比實(shí)驗(yàn),以說明我們的方法在惡意廣告的檢測(cè)精度上更具優(yōu)勢(shì).
JavaScript的動(dòng)態(tài)插樁工具Jalangi運(yùn)行在Linux系統(tǒng)中,我們?cè)诖矸?wù)器端使用OSX系統(tǒng)對(duì)網(wǎng)頁(yè)進(jìn)行插樁,在Windows 7系統(tǒng)上用Firefox上對(duì)網(wǎng)頁(yè)進(jìn)行瀏覽,并在控制臺(tái)獲取廣告相關(guān)的調(diào)用路徑,然后通過調(diào)用路徑分析廣告相關(guān)的JavaScript腳本文件.
我們隨機(jī)選取Alexa排名網(wǎng)站中的21個(gè)網(wǎng)站(包括13個(gè)國(guó)外網(wǎng)站和8個(gè)國(guó)內(nèi)網(wǎng)站),作為實(shí)驗(yàn)對(duì)象,以追蹤網(wǎng)站中廣告相關(guān)的JavaScript文件調(diào)用、傳遞的詳細(xì)過程.
本文實(shí)驗(yàn)獲取的廣告相關(guān) JavaScript函數(shù)調(diào)用路徑中插入標(biāo)簽的方式包括:通過 JS函數(shù) insertBefore和appendChild分別插入script、img、a、iframe標(biāo)簽;或通過document.write寫入一些標(biāo)簽;或通過innerHTML插入iframe標(biāo)簽.之后,統(tǒng)計(jì)各種插入方式的操作次數(shù).另外,我們還取到了廣告路徑中相關(guān)的JavaScript腳本文件,對(duì)每個(gè)文件解析其抽象語(yǔ)法樹,然后統(tǒng)計(jì)文件中insertBefore、appendChild、document.wirte、innerHTML出現(xiàn)的次數(shù).這種靜態(tài)方法只能獲取到各種操作的次數(shù),不能獲取到插入標(biāo)簽的種類.實(shí)驗(yàn)過程中,比較這兩種方式所獲取信息的差異,并給出具體的結(jié)論.
5.3.1 實(shí)驗(yàn)數(shù)據(jù)及其分析
通過對(duì)網(wǎng)頁(yè)動(dòng)態(tài)執(zhí)行過程的記錄和分析,我們不僅可以獲取廣告相關(guān)的函數(shù)調(diào)用路徑,還可以獲取網(wǎng)站 JS文件數(shù)量、廣告的插入方式.對(duì)于靜態(tài)分析方法,可以通過遍歷廣告相關(guān)的JS文件的抽象語(yǔ)法樹獲取廣告插入的操作方式,但是無法獲取操作標(biāo)簽的種類.
表1中給出了網(wǎng)頁(yè)動(dòng)態(tài)執(zhí)行中所涉及的JS文件、廣告相關(guān)JS文件和廣告相關(guān)JS片段數(shù)量,另外,還列出了插樁前后訪問時(shí)間的對(duì)比情況以及實(shí)際記錄的Trace長(zhǎng)度情況.從平均數(shù)來看,這些網(wǎng)站平均要載入72個(gè)JS文件,其中廣告相關(guān)的JS文件有7個(gè),這說明,在運(yùn)行過程中會(huì)動(dòng)態(tài)載入或生成相當(dāng)多數(shù)量的JS文件或片段.如果只通過靜態(tài)方法分析網(wǎng)頁(yè)中的JS文件,則不能獲得動(dòng)態(tài)執(zhí)行過程中載入的JS文件或片段,因而也就無法精確識(shí)別網(wǎng)頁(yè)中的廣告.另外,通過訪問時(shí)間的對(duì)比,我們發(fā)現(xiàn)本文方法的性能開銷通常是2~10X,處于用戶可以接受的范圍內(nèi).關(guān)于實(shí)際記錄的Trace長(zhǎng)度情況,我們發(fā)現(xiàn)一個(gè)頁(yè)面上會(huì)包含多個(gè)廣告(通常有2~10個(gè)),且廣告代碼調(diào)用路徑的長(zhǎng)度在 1~34之間,平均數(shù)在3~9之間,這表明,廣告的調(diào)用、傳播路徑還是比較長(zhǎng)的,中間經(jīng)過了多次跳轉(zhuǎn),這很大程度上增加了安全風(fēng)險(xiǎn).
Table 1 Numbers of JS files, ads-related JS files and ads-related JS snippets表1 網(wǎng)頁(yè)動(dòng)態(tài)執(zhí)行中所涉及的JS文件、廣告相關(guān)JS文件和廣告相關(guān)JS片段數(shù)量
圖9中顯示了網(wǎng)站JS腳本動(dòng)態(tài)運(yùn)行過程中appendChild、insertBefore、document.write和innerHTML的比例關(guān)系,可以看出,appendChild使用得最多(超過 40%),其次為 insertBefore(37%),而 document.write和innerHTML所占比例較少(分別為14%和6%).
我們同樣使用靜態(tài)分析方法統(tǒng)計(jì)了網(wǎng)站中 JS文件中 appendChild、insertBefore、document.write和innerHTML的比例關(guān)系(如圖10所示),可以看出,appendChild方法占比也是超過了40%,而insertBefore的比例有所減少(25%),innerHtml的數(shù)量大幅增加(25%).
通過比較圖9和圖10,我們發(fā)現(xiàn):通過innerHtml屬性來動(dòng)態(tài)加載HTML網(wǎng)頁(yè)中廣告的方式比較少見(6%),而在網(wǎng)頁(yè)源代碼中經(jīng)常能看到 innerHtml屬性(25%),這表明,該屬性雖然常見,但大部分是與廣告加載無關(guān)的;與此相反,document.write在網(wǎng)頁(yè)源代碼中不算常見(2%),但還較多地用來動(dòng)態(tài)加載HTML網(wǎng)頁(yè)中的廣告(14%),這表明,該屬性雖然不大常見,但大部分是與廣告加載相關(guān)的.
圖 11中給出了網(wǎng)頁(yè)JS腳本運(yùn)行過程中動(dòng)態(tài)生成 iframe、script、image和 a標(biāo)簽所占的比例,可以看出,在這些含廣告的網(wǎng)站動(dòng)態(tài)生成的標(biāo)簽中 script(52%)和 iframe(28%)標(biāo)簽占了大部分(80%),這說明,廣告腳本在運(yùn)行過程中會(huì)動(dòng)態(tài)生成很多腳本和網(wǎng)頁(yè),這正是廣告分析的難點(diǎn)所在.作為廣告展示的image標(biāo)簽占17%,這說明,廣告主要以圖片的形式進(jìn)行展示,而從廣告網(wǎng)頁(yè)的加載開始到最終顯示出廣告,會(huì)經(jīng)歷多次的動(dòng)態(tài)生成腳本和網(wǎng)頁(yè)的過程,有非常復(fù)雜的調(diào)用路徑,這使得惡意廣告的入侵成為可能.
我們的動(dòng)態(tài)分析可以監(jiān)控到廣告加載的全過程,從而進(jìn)行及時(shí)、有效的干預(yù).而只進(jìn)行靜態(tài)分析,是無法檢測(cè)到這些動(dòng)態(tài)生成的惡意廣告代碼的.
5.3.2 實(shí)例分析
如圖12所示,匿名函數(shù)1中有一個(gè)三目運(yùn)算,當(dāng)條件(0===TRC.trkRequestStatus)不滿足時(shí),調(diào)用函數(shù)_(函數(shù)2);函數(shù)_執(zhí)行了一系列操作之后,調(diào)用函數(shù)T(函數(shù)3);函數(shù)T調(diào)用了函數(shù)C(函數(shù)4);函數(shù)C中(https:"==ea?"https://sb":"http://b")+".scorecardresearch.com/beacon.js)為一個(gè)三目運(yùn)算操作和一個(gè)字符串拼接操作,并把運(yùn)算后的字符串作為參數(shù)傳遞給a,{async:!0}傳遞給參數(shù)c,在函數(shù)C中,創(chuàng)建script標(biāo)簽e,然后設(shè)置e的src為a,即https://sb.scorecardresearch.com/beacon.js或者h(yuǎn)ttp://b.scorecardresearch.com/beacon.js,并且判斷c.async的值作為e的屬性設(shè)置的依據(jù),最后用insertBefore操作將script標(biāo)簽寫入網(wǎng)頁(yè)中.
由此,我們使用擴(kuò)展后的Jalangi進(jìn)行插樁并記錄執(zhí)行軌跡,形成的函數(shù)調(diào)用路徑如下所示:
其中,“_”“T”“C”分別表示函數(shù)名,unnamed 是我們?yōu)槟涿瘮?shù)取的一個(gè)標(biāo)識(shí),cache/cdn.taboola.com/937d7f3e84aa424b9efca0a72b0ec608/loader.js表示loader.js在jalangi中存放的文件路徑,114:162298:114:162301表示當(dāng)前函數(shù)在loader.js腳本中的位置為從第114行的162 298列~第114行的162 301列,因?yàn)槟_本文件的內(nèi)容是經(jīng)過壓縮的,所以列數(shù)多,代碼難理解.上述調(diào)用路徑為“unnamed→_→T→C→insertBeforescriptbeacon.js”.在beacon.js中還有一系列的函數(shù)調(diào)用.仔細(xì)觀察函數(shù)_,還調(diào)用了A函數(shù),此處又有另一條函數(shù)調(diào)用路徑.這表明,實(shí)際網(wǎng)頁(yè)中存在很多代碼壓縮的情況,并且函數(shù)之間的調(diào)用關(guān)系非常復(fù)雜,如果采用人工審查代碼的方式,是很難識(shí)別這些廣告文件中的函數(shù)調(diào)用關(guān)系的.
JavaScript在 Web應(yīng)用中發(fā)揮著重要作用,具有語(yǔ)法靈活性和高度動(dòng)態(tài)性,易于使用,但代碼的可維護(hù)性不夠好.比如,JavaScript在運(yùn)行時(shí)被廣泛用來和 DocumentObjectModel(DOM[6])元素進(jìn)行異步交互[7],其動(dòng)態(tài)性和松散性使JavaScript代碼易錯(cuò),且定位困難[8-11].
基于Jalangi動(dòng)態(tài)分析框架[5],可以檢查JavaScript類型的一致性[12]或提高just-in-time(JIT)性能[13].另外,工具DLint[14]是在Jalangi的基礎(chǔ)上實(shí)現(xiàn)的,使用動(dòng)態(tài)分析方法檢查JavaScript代碼質(zhì)量,由一個(gè)通用框架和一組可擴(kuò)展的地址和特定規(guī)則的檢查器組成,能夠解決被靜態(tài)方法遺漏的缺陷.
文獻(xiàn)[15]在文獻(xiàn)[16]的基礎(chǔ)上提出了一個(gè)自動(dòng)定位技術(shù),通過追蹤和后向切片,實(shí)現(xiàn)對(duì) JavaScript的動(dòng)態(tài)分析,解決了包括eval、匿名函數(shù)處理的困難.此外,HTML元素和JavaScript代碼之間通過瀏覽器相互作用,加劇了客戶端JavaScript代碼的維護(hù)問題.文獻(xiàn)[17]提出了一種JavaScript動(dòng)態(tài)切片技術(shù)JS-Slicer,使得理解和調(diào)試客戶端JavaScript代碼變得容易.JS-Slicer在動(dòng)態(tài)分析框架Jalangi的基礎(chǔ)上,結(jié)合動(dòng)態(tài)和靜態(tài)分析所得結(jié)果,精確地捕獲運(yùn)行時(shí)的依賴信息.
隨著互聯(lián)網(wǎng)的發(fā)展,在線廣告越來越多地被用于非法途徑,如傳播惡意軟件、詐騙、點(diǎn)擊詐騙行為等.為了理解這些惡意廣告活動(dòng)的嚴(yán)重性,文獻(xiàn)[1-3]中研究了通過廣告聯(lián)盟所傳播廣告節(jié)點(diǎn)的拓?fù)浣Y(jié)構(gòu),以此來獲得惡意廣告的傳播行為和特點(diǎn),文獻(xiàn)[4]分析了3個(gè)月內(nèi)爬取的廣告相關(guān)的網(wǎng)頁(yè)痕跡,揭示了惡意廣告的猖獗,進(jìn)而從惡意廣告節(jié)點(diǎn)及其相關(guān)的內(nèi)容傳遞路徑來識(shí)別出惡意廣告的特征,并構(gòu)建了一個(gè)檢測(cè)系統(tǒng).
出于隱私、介入性和安全性等方面的考慮,現(xiàn)有一些技術(shù)和工具來攔截、屏蔽互聯(lián)網(wǎng)廣告,如:AdBlocke[18]、AdblockPlus[19]、Ghostery[20].這些工具通過維護(hù)一系列基于URL的正則表達(dá)式(EasyList[21]),將其與網(wǎng)頁(yè)上獲取的URL進(jìn)行匹配而過濾廣告.文獻(xiàn)[22]使用針對(duì)JavaScript源代碼的靜態(tài)程序分析,識(shí)別用于加載并顯示廣告的JavaScript代碼,通過特征訓(xùn)練,得到廣告相關(guān)腳本的分類器,從而實(shí)現(xiàn)廣告的攔截.與其相反,為了保障廣告商的合法權(quán)益,WebRanz[23]利用隨機(jī)化機(jī)制來使得廣告攔截器失效,通過使用 WebRanz,內(nèi)容發(fā)布者可以不斷改變內(nèi)部HTML元素ID以及元素屬性,而不會(huì)影響它們的視覺效果和功能.
現(xiàn)有互聯(lián)網(wǎng)廣告的檢測(cè)方法主要集中在靜態(tài)模式匹配、靜態(tài)特征匹配等,無法對(duì)混淆過后的域名和選擇器進(jìn)行有效檢測(cè),并且主要通過主觀判定來識(shí)別、確定廣告的特征,檢測(cè)精度低.相應(yīng)地,本文工作的主要目的是獲取廣告代碼運(yùn)行時(shí)的調(diào)用路徑,以得到廣告相關(guān)的JS文件并確定廣告插入的操作方式等信息,可以應(yīng)用到廣告代碼(包括混淆代碼甚至惡意廣告代碼等)的識(shí)別中,并有效提高檢測(cè)精度,部分工作細(xì)節(jié)參加文獻(xiàn)[24].
作為互聯(lián)網(wǎng)最成熟的商業(yè)模式之一,在線廣告一方面有助于促進(jìn)互聯(lián)網(wǎng)生態(tài)系統(tǒng)的健康發(fā)展,但也可能影響用戶的網(wǎng)頁(yè)瀏覽體驗(yàn)以及帶來潛在的安全風(fēng)險(xiǎn).現(xiàn)有的在線廣告屏蔽插件通過設(shè)置黑名單的方式實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)廣告的檢測(cè)和屏蔽,但無法識(shí)別不在名單中的廣告,也無法獲取廣告代碼的調(diào)用路徑.
本文的研究對(duì)象是來自于廣告聯(lián)盟的動(dòng)態(tài)廣告,這些廣告是目前在線廣告的主要存在形式.本文的工作是通過使用 JavaScript的動(dòng)態(tài)插樁工具 Jalangi獲取自動(dòng)執(zhí)行的廣告代碼第三方 JavaScript函數(shù)調(diào)用路徑.為此,我們?yōu)镴avaScript函數(shù)動(dòng)態(tài)綁定了一個(gè)存儲(chǔ)調(diào)用路徑信息的屬性,分別識(shí)別廣告代碼調(diào)用路徑的起始、中間以及終止?fàn)顟B(tài),并對(duì)于 setTimeout、setInterval等函數(shù)進(jìn)行特殊處理以保證函數(shù)調(diào)用鏈的完整傳遞.另外,還對(duì)跨iframe的調(diào)用路徑進(jìn)行拼接處理.此外,我們統(tǒng)計(jì)了廣告插入操作方式的類型(insertBefore、appendChild、document.wirte、innerHTML)和比例,并與遍歷抽象語(yǔ)法樹的靜態(tài)方法操作數(shù)量進(jìn)行了對(duì)比,以此說明本文方法的有效性.
在實(shí)驗(yàn)過程中,我們發(fā)現(xiàn)了一些用于分析用戶行為和記錄用戶 cookie的腳本文件,如 analytics.js,bkcoretag.js等.這些文件的特征和廣告代碼文件的特征比較相似,尤其體現(xiàn)在動(dòng)態(tài)生成、傳播上.分析用戶行為和記錄用戶 cookie也會(huì)在一定程度上降低用戶的瀏覽體驗(yàn)感受,實(shí)際上也是一種對(duì)用戶隱私的侵害,可以考慮將其一并作為廣告相關(guān) JavaScript文件進(jìn)行屏蔽.因此,在后續(xù)研究中,我們會(huì)通過追蹤代碼調(diào)用路徑的方式,進(jìn)一步區(qū)分該類分析文件與廣告文件的特征,并應(yīng)用于惡意廣告的檢測(cè)和屏蔽方面.