為什么“瀏覽器劫持”能夠如此猖狂呢?放眼眾多論壇的求助貼,我們不時可以看到諸如“我的IE被主頁被改了,我用殺毒工具掃了一遍都沒發(fā)現(xiàn)病毒,我把主頁改回自己的地址,可是一重啟它又回來了!”、“我的系統(tǒng)一開機就跳出一個廣告,我明明用了最新版的殺毒軟件的??!”等這類關于IE異常問題的求助,80%的提問者都表示納悶,他們已經(jīng)安裝了殺毒軟件,可是IE仍然被“黑”了,這又是為什么?
其實這些都是典型的“瀏覽器劫持”現(xiàn)象,但是受害者不是已經(jīng)安裝了殺毒軟件嗎?為什么瀏覽器依然躲不過這只黑手?許多用戶對這個領域都存在一種誤區(qū)心理:瀏覽器劫持?我有最新的殺毒軟件,我不怕!
于是,當他們遭遇“瀏覽器劫持”時,驚訝了。
要知道,殺毒軟件自身也只是一種輔助工具,它不可能完全保護系統(tǒng)的安全,更何況,殺毒軟件用戶必須知道一個事實:“瀏覽器劫持”的攻擊手段是可以通過被系統(tǒng)認可的“合法途徑”來進行的!殺毒軟件只能通過“特征碼”的形式來判斷程序是否合法,但這是建立在人為定義以后的,而實施“瀏覽器劫持”的程序可以有很多,防不勝防。
為什么說“瀏覽器劫持”可以說是合法的呢?因為大部分瀏覽器劫持的發(fā)起者,都是通過一種被稱為“BHO”(Browser Helper Object,瀏覽器輔助對象)的技術手段植入系統(tǒng)的。
BHO是微軟早在1999年推出的作為瀏覽器對第三方程序員開放交互接口的業(yè)界標準,它是一種可以讓程序員使用簡單代碼進入瀏覽器領域的“交互接口”(INTERACTIVED Interface)。通過BHO接口,第三方程序員可以自己編寫代碼獲取瀏覽器的一些行為(Action)和事件通知(Event),如“后退”、“前進”、“當前頁面”等,甚至可以獲取瀏覽器的各個組件信息,像菜單、工具欄、坐標等。由于BHO的交互特性,程序員還可以使用代碼去控制瀏覽器的行為,比如常見的修改替換瀏覽器工具欄、在瀏覽器界面上添加自己的程序按鈕等操作,而這些操作都被視為“合法”的,這就是一切罪惡根源的開始。
BHO的出現(xiàn)幫助程序員更好的打造個性化瀏覽器或者為自己的程序?qū)崿F(xiàn)了方便簡潔的交互功能,可以說,如果沒有BHO接口的誕生,我們今天就不能用一些工具實現(xiàn)個性化IE的功能了。從某一方面來看,BHO的確是各種繽紛網(wǎng)絡互動功能的幕后功臣,但是一切事物都是有兩面性的,這個恒古不變的真理同樣對BHO有效,于是就有了今天讓安全界頭痛的“瀏覽器劫持”的攻擊手段誕生。
看看前面我提到的BHO接口特性,你想到了什么?BHO可以獲知和實現(xiàn)瀏覽器的大部分事件和功能,也就是說,它可以利用少量的代碼控制瀏覽器行為。程序員可以設計出一個BHO按鈕以實現(xiàn)用戶點擊時通知瀏覽器跳轉(zhuǎn)到某個頁面完成交互功能,當然就可以進一步寫出控制瀏覽器跳轉(zhuǎn)到他想讓用戶去的頁面,這就是最初的“瀏覽器劫持”的成因:BHO劫持。
在描述BHO劫持之前,我們先要對BHO接口的啟動做個簡單介紹:符合BHO接口標準的程序代碼被寫為DLL動態(tài)鏈接庫形式在注冊表里注冊為COM對象,還要在BHO接口的注冊表入口處進行組件注冊,以后每次IE啟動時都會通過這里描述的注冊信息調(diào)用加載這個DLL文件,而這個DLL文件就因此成為IE的一個模塊(BHO組件),與IE共享一個運行周期,直到IE被關閉。
IE啟動時,會加載任何BHO組件,這些組件直接進入IE領域,而IE則成為它們的父進程和載體,從此IE的每一個事件都會通過IUnknown接口傳遞到BHO用以提供交互的IObjectWithSite接口里,這是BHO實現(xiàn)與IE交互的入口函數(shù)。
BHO接收到IE接口傳遞來的參數(shù)后開始判斷IE正在做什么,理論上BHO可以獲取IE的大部分事件,然后根據(jù)程序員編寫的代碼,BHO持有對特定事件做出反應的決定權,例如一個可以實現(xiàn)“中文網(wǎng)址”的BHO,就是通過GetSite方法獲取到IE當前打開的站點URL(或通過IURLSearchHook接口來獲知),如果BHO發(fā)現(xiàn)獲取到的URL和內(nèi)置的判斷條件匹配,該BHO就會啟用SetSite方法強制IE跳轉(zhuǎn)到程序員設定的頁面去,這個過程就是利用about:blank篡改主頁的“瀏覽器劫持”方法之一,它的實現(xiàn)原理其實很簡單,程序員編寫一個惡意BHO組件,當它獲取到IE窗口的當前站點為“about:blank”時就強制IE內(nèi)部跳轉(zhuǎn)到指定的廣告頁面,于是鬧出了不久之前沸沸揚揚的“IE空白頁劫持事件”。
了解了這種類似惡作劇的作案手段,要解決它就容易了,只要找到并刪除這個隱藏在系統(tǒng)里的BHO程序即可。
除了這類“廣告軟件”性質(zhì)的BHO,還有一種利用IURLSearchHook接口實現(xiàn)的另一類更隱蔽的BHO,這種BHO從某些方面來說大概不算BHO,因為它并不是響應IUnknown,而是等待IE創(chuàng)建IURLSearchHook來啟動。IURLSearchHook被瀏覽器用來轉(zhuǎn)換一個未知的URL協(xié)議地址,當瀏覽器企圖去打開一個未知協(xié)議的URL地址時,瀏覽器首先嘗試從這個地址得到當前的協(xié)議,如果不成功,瀏覽器將尋找系統(tǒng)里所有注冊為“URL Search Hook”(資源搜索鉤子,USH)的對象并把這個IE不能理解的地址發(fā)送過去,如果某個USH對象“認識”這個地址,它就返回一個特定的標識告訴IE它知道怎么打開這個地址,然后IE就根據(jù)約定的方法調(diào)用它,最終打開這個地址。其實USH對象并不陌生,我們一些偷懶的用戶就經(jīng)常為了省事而不輸入“http://”,但是IE最終還是能認出并打開某個地址,就是USH的功勞,但是這一點又被惡意程序員拿來磨刀了,通過創(chuàng)建自己的USH對象,惡意程序員能夠命令IE在找不到一些網(wǎng)站時自動跳轉(zhuǎn)到事先設置的站點里,如果這個站點帶毒或者掛馬,用戶就完了。
這類BHO的解決方法和前面一樣,只是它比較隱蔽,除非用戶經(jīng)常偷懶,否則可能直到系統(tǒng)崩潰也不會知道自己已經(jīng)感染了這種東西。也許你會說,只要用戶的輸入永遠不會讓IE無法識別,這種滲透不就白費了?但是事實不容樂觀,我們無法得知BHO作者還會不會通過其他方法攔截IE,說不定每隔一段時間就讓IE彈出一個廣告呢?
上面說了這么多BHO和IE合作搞破壞的事例,可能會給讀者造成一種“BHO必須在IE傳遞數(shù)據(jù)后才能行動”的誤解,然而事實并非如此,瀏覽器自身也是一個標準的可執(zhí)行程序,而BHO只是借用這個程序進程啟動的DLL,它并非API那種要用的時候就讓你過來忙活,忙活完了就一腳踹開的奴隸形態(tài)DLL,前面說過了,BHO是一種在瀏覽器加載時一同啟動的例程,它相當于一種自身運行邏輯不太明確的子進程(里面都是對IE事件的響應和操作代碼),這個特性就造成了BHO DLL和API DLL本質(zhì)的區(qū)別,BHO并不需要所有事件都必須依賴這個大家伙,它可以有自己決定的權利,只要適當?shù)男薷?,就能用BHO實現(xiàn)類似DLL木馬的功能,當然,這并不是說我們就能在IE眼皮下公然的肆無忌彈干壞事的,由于BHO自身是作為IE子進程啟動的,它就必須受到一些限制,例如程序員不能在里面自己創(chuàng)建網(wǎng)絡連接,這樣會導致IE報錯崩潰并供出你寫的DLL,害怕BHO成為另一種后門的用戶可以松口氣了,要在BHO里實現(xiàn)Winsock大概只能在IE休息的時候才可以,但是會有哪個用戶開著個開空IE什么事情都不做呢?
但這并不是說BHO就一定能無害了,雖然用它不能做到遠程控制,但是別忘記,BHO能看到IE的所有東西,也就能任意的訪問用戶文件和注冊表,在這個條件成立的前提下,入侵者可以編寫代碼查找用戶隱私,然后在適當時候通過SetSite提交出去——誰叫現(xiàn)在Webmail這么流行呢?這就是為什么許多廠商發(fā)布諸如“中文網(wǎng)址”、“網(wǎng)絡搜索”、“IE定制”、“IE監(jiān)視”這些功能的BHO的同時都保證“不搜集用戶隱私”的原因,只要你想要,BHO就能得到一切。
有些人也許會想,既然BHO是微軟瀏覽器的權利,那我不用IE了,我用Opera、Firefox不行?對于這點固然無可厚非,但是你用不用Windows?用不用共享軟件?如果你用Windows,那么,你仍然可能處于被BHO接觸到的世界,因為Windows本身就是和IE緊密結合的,這就把“IE進程”的范圍給擴大了,細心的用戶大概會發(fā)現(xiàn),IE里能直接訪問“我的電腦”,“我的電腦”窗口也能迅速變成IE,因為它們實質(zhì)都是依賴于IE內(nèi)核的,正因為這個原因,BHO可以在你打開一個文件夾時跟著偷偷啟動。同時,現(xiàn)在的網(wǎng)絡正處于一種“共享軟件捆綁戰(zhàn)略”大肆實施的時代,你再小心也不能避免某些共享軟件固定捆綁了BHO的行為,安裝后你才會發(fā)現(xiàn)文件夾上又多了個什么“助手”、“搜索”了。要想徹底逃開BHO的圍困,大概只能放棄使用Windows了。
三. Hook,你鉤住瀏覽器了
“Life finds its way.”——《侏羅紀公園》
正如《侏》里的這句話一樣,入侵者也在不斷尋找他們的新出路,雖然上面我說了這么多BHO的負面事例,但是真正的危機并不是只有BHO的,在一些使用BHO行不通的場合里,入侵者開始投擲他們的鉤子。
什么是鉤子?讓我們先看看它的官方定義:
鉤子(Hook),是Windows消息處理機制的一個平臺,應用程序可以在上面設置子程以監(jiān)視指定窗口的某種消息,而且所監(jiān)視的窗口可以是其他進程所創(chuàng)建的。當消息到達后,在目標窗口處理函數(shù)之前處理它。鉤子機制允許應用程序截獲處理window消息或特定事件。
鉤子實際上是一個處理消息的程序段,通過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。每當特定的消息發(fā)出,在沒有到達目的窗口前,鉤子程序就先捕獲該消息,亦即鉤子函數(shù)先得到控制權。這時鉤子函數(shù)即可以加工處理(改變)該消息,也可以不作處理而繼續(xù)傳遞該消息,還可以強制結束消息的傳遞。
可能上面的官方定義對一部分讀者理解有點困難,其實,鉤子就像是一切程序的“先知”,一個實現(xiàn)了鉤子的程序自身雖然也是普通程序,但是它總能在別的程序得到數(shù)據(jù)之前就已經(jīng)知道了一切,這是為什么呢?對Windows系統(tǒng)有一定了解的讀者應該知道,Windows系統(tǒng)是一個通過“信息處理機制”運作的系統(tǒng),在這個系統(tǒng)里傳遞的數(shù)據(jù)都是通過“消息”(Message)的形式發(fā)送的,各個消息都遵循了官方的約定,否則就不能讓系統(tǒng)產(chǎn)生回應。而且這個傳遞步驟是顛倒的,例如我們關閉了某個程序,我們可能會認為是程序自己關閉后通知系統(tǒng)的,其實不然,當用戶點擊關閉按鈕的時候,Windows就會把一個叫做WM_CLOSE的消息傳遞給這個程序,程序接收到消息后就執(zhí)行卸載自身例程的操作。理解了這點,就能知道鉤子的原理了,所謂鉤子程序,就是利用了系統(tǒng)提供的Hook API,讓自己比每一個程序都提前接收到系統(tǒng)消息,然后做出處理,如果一個鉤子攔截了系統(tǒng)給某個程序的WM_CLOSE消息,那么這個程序就會因為接收不到關閉消息而無法關閉自身。除了消息以外,鉤子還可以攔截API,像我們都熟悉的屏幕翻譯軟件就是Hook了一些文本輸出函數(shù)如TextOutA而達到了目的。
Hook技術讓編程人員可以輕松獲取其他程序的一些有用數(shù)據(jù)或傳遞相關數(shù)據(jù),像現(xiàn)在常見的一些游戲外掛,它們就是利用Hook技術鉤住了游戲窗體,然后就可以識別游戲里面的行為和模擬發(fā)送按鍵鼠標消息,最終實現(xiàn)電腦自己玩游戲的功能。把這個技術應用到瀏覽器上面,就成了另一種控制瀏覽器行為的方法。
鉤子有兩種,本地鉤子(Local Hook)和全局鉤子(Global Hook),本地鉤子只在本進程里起作用,故不屬于討論范圍;全局鉤子代碼必須以DLL形式編寫,以便在鉤子生效時被其它進程所加載調(diào)用,因此我們看到的大部分Hook程序都是DLL形式的。
其實之前提到的BHO也可以視為一種針對IE的鉤子,它鉤的是IE的事件,這就是IE與BHO交互的起點,但是對于再復雜一點的操作,例如判斷IE下載的是GIF圖片還是JPEG圖片,BHO無能為力,因為它僅僅知道IE的事件為DownloadBegin和DownloadComplete,對于具體內(nèi)容,IE本身是不會告訴它的,否則IE豈不是要忙死了?至少我也沒見過哪個領導還需要向秘書匯報中午吃了雞肉還是鴨肉的吧,BHO可不是IE的老婆,或者說IE沒有氣管炎。
所以,為了得到IE的更多數(shù)據(jù),程序員開始鉤IE了。與BHO不同,鉤子不需要被動的等待IE事件,它直接和IE形成上司對下屬的關系,這次輪到IE要做什么都得經(jīng)過它批準了。Hook形式的控制不需要DLL文件必須與IE的注冊表入口產(chǎn)生組件關系,它可以是一個獨立的DLL,通過Rundll32.exe或自帶的Loader EXE啟動,而且由于它屬于Hook形式, 在鉤子有效的情況下會被系統(tǒng)自動插入其他程序的進程中,是不是有點像DLL木馬呢?
IE鉤子程序載入進程后便能獲知所有的消息類型、API和內(nèi)容,一旦發(fā)現(xiàn)某個符合要求的消息,如IE執(zhí)行了某個事件,或者用戶輸入了特定內(nèi)容,鉤子的處理代碼就開始工作了,它先攔截系統(tǒng)發(fā)送給IE的消息,然后分析消息內(nèi)容,根據(jù)不同消息內(nèi)容作出修改后再發(fā)給IE,就完成了一次Hook篡改過程。用著名的3721實名搜索做例子,一些人會以為它是采用了BHO或者IURLSearchHook完成中文域名的識別跳轉(zhuǎn)的,其實它是用了能夠第一個得到Windows消息的Hook技術,這樣一來就可以避免被其他的競爭對手搶先解析域名了:3721的主程序就是一個Hook DLL,它監(jiān)視IE地址欄的消息,一旦用戶輸入的是中文,它便在其他BHO類插件工作之前攔截了這個消息,并調(diào)用自身代碼完成中文域名到英文URL的轉(zhuǎn)換工作,然后返回(也可能與自己的BHO DLL配合)一個讓IE跳轉(zhuǎn)到英文URL的消息,完成域名的翻譯任務。
IE鉤子能幫助程序員用少量代碼完成更多的IE交互工作,但是一旦這個鉤子被用于犯罪,其后果也是嚴重的,惡意程序員可以寫一個攔截IE輸入的鍵盤鉤子,達到竊取密碼的作用,這樣無論你是用HTTP明文協(xié)議還是SecurityHTTP加密協(xié)議都不能逃避密碼被盜的下場了,因為它抓的是你在IE里的輸入,后面的數(shù)據(jù)傳輸已經(jīng)不重要了。
四. Winsock LSP
全稱為“Windows Socket Layered Service Provider”(分層服務提供商),這是Winsock 2.0才有的功能,它需要Winsock支持服務提供商接口(Service Provider Interface,SPI)才能實現(xiàn),SPI是一種不能獨立工作的技術,它依賴于系統(tǒng)商已經(jīng)存在的基本協(xié)議提供商,如TCP/IP協(xié)議等,在這些協(xié)議上派分出的子協(xié)議即為“分層協(xié)議”,如SSL等,它們必須通過一定的接口函數(shù)調(diào)用,LSP就是這些協(xié)議的接口。
通過LSP,我們可以比分析基本協(xié)議更簡單的得到我們想要的數(shù)據(jù)內(nèi)容,如直接得到系統(tǒng)上運行的瀏覽器當前正在進行傳輸?shù)牡刂泛蛢?nèi)容,不管這個瀏覽器是IE,還是Opera或Firefox,因為LSP是直接從Winsock獲取信息的,即使不用微軟生產(chǎn)的汽車,至少你這輛汽車一直是在微軟建造的公路上跑的吧。
LSP用在正途上可以方便程序員們編寫監(jiān)視系統(tǒng)網(wǎng)絡通訊情況的Sniffer,可是現(xiàn)在常見的LSP都被用于瀏覽器劫持,使用戶又多了個噩夢。
五. 亡羊補牢,還是居安思危?
也許大部分家庭用戶都是在經(jīng)歷過一次入侵或中毒事件后才知道安全防范的重要性的,能亡羊補牢當然是好事,但是如果能對自己的要求提高一點,做到未雨綢繆豈不是更好?我們總是依賴于別人的技術,依賴于模式化的殺毒手段,但那些始終都是別人的東西,控制權不能掌握在自己手上,這并不是很好的事情,也許,該是暫時放棄游戲掛級、搜集明星電影,好好研讀一下安全方面和系統(tǒng)原理書籍的時候了,否則在這個不安全的網(wǎng)絡中,我們隨時可能會迷失自己。
可能有人會想,小金又在發(fā)感慨了。也許是的,因為清除“瀏覽器劫持”一般都需要手工進行,雖然現(xiàn)在已經(jīng)有了多個檢測瀏覽器劫持的工具如HijackThis、Browser Hijack Recover等軟件面世,但是如果你抱著和以往使用殺毒工具那樣“一開掃描就安枕無憂”想法的話,你會發(fā)現(xiàn)自己真的會迷失了,由于BHO的特殊性(別忘記,它是合法的),這些工具只會把系統(tǒng)的進程、BHO項目、啟動項、LSP等需要有一定技術基礎方能理解的東西顯示給你,然后由你自己決定IE的明天,如果你不曾重視過安全技術,那么就會覺得這些工具如同另一種折磨你的病毒了。
學,還是不學?這是個必須考慮的問題……
http://bbs.yesky.com/bbs.php?url=forumdisplay.php?fid=130