一. 誰誤導了浏覽器
今天是大年初二, 王 先生家中來了許多客人,把平時埋頭于工作的 王 先生弄了個手忙腳亂,由于客人帶來的幾個小孩子嚷嚷着要出去上網, 王 先生隻好把寝室裡的電腦讓給了這一群孩子玩,好容易到了晚上,客人散盡, 王 先生想在休息前上網浏覽一下新聞,可是當他打開IE的時候,卻發現它自動連接配接到一個莫名其妙的網站去了,而且收藏夾裡也多了一些奇怪的網址, 王 先生擔心是系統感染了病毒,趕緊輸入一個線上殺毒工具的網址,結果IE打開的卻是另一個不知所謂的網站。看着IE位址欄裡準确無誤的殺毒工具網址和下面那根本扯不上關系的内容, 王 先生真的手忙腳亂了……
相信不少使用者也遇到過與之類似的奇怪事情,究竟是誰,把我們的浏覽器領到了一處陌生的地方呢?
近年來,針對浏覽器的攻擊手段層出不窮,對浏覽器的滲透攻擊逐漸成為入侵者攻破使用者層層防禦的首要目标,在“釣魚”(Publishing)危機尚未解除的時候,另一種攻擊方式也在同時進行着,這就是“浏覽器劫持”——故意誤導浏覽器行進路線的策劃者。
“浏覽器劫持”(Browser Hijack)是一種不同于普通病毒木馬感染途徑的網絡攻擊手段,它的滲透途徑很多,目前最常見的方式有通過BHO、DLL插件、Hook技術、Winsock LSP等載體達到對使用者的浏覽器進行篡改的目的。這些載體可以直接寄生于浏覽器的子產品裡,成為浏覽器的一部分,進而直接操縱浏覽器的行為,輕者把使用者帶到自家門戶網站,嚴重的則會在使用者計算機中收集敏感資訊,危及使用者隐私安全。“浏覽器劫持”的後果非常嚴重,使用者隻有在受到劫持後才會發現異常情況,但是這時候已經太遲了。目前,浏覽器劫持已經成為Internet使用者最大的威脅之一。
二. BHO,你是助手還是敵人?
為什麼“浏覽器劫持”能夠如此猖狂呢?放眼衆多論壇的求助貼,我們不時可以看到諸如“我的IE被首頁被改了,我用殺毒工具掃了一遍都沒發現病毒,我把首頁改回自己的位址,可是一重新開機它又回來了!”、“我的系統一開機就跳出一個廣告,我明明用了最新版的防毒軟體的啊!”等這類關于IE異常問題的求助,80%的提問者都表示納悶,他們已經安裝了防毒軟體,可是IE仍然被“黑”了,這又是為什麼?
其實這些都是典型的“浏覽器劫持”現象,但是受害者不是已經安裝了防毒軟體嗎?為什麼浏覽器依然躲不過這隻黑手?許多使用者對這個領域都存在一種誤區心理:浏覽器劫持?我有最新的防毒軟體,我不怕!
于是,當他們遭遇“浏覽器劫持”時,驚訝了。
要知道,防毒軟體自身也隻是一種輔助工具,它不可能完全保護系統的安全,更何況,防毒軟體使用者必須知道一個事實:“浏覽器劫持”的攻擊手段是可以通過被系統認可的“合法途徑”來進行的!防毒軟體隻能通過“特征碼”的形式來判斷程式是否合法,但這是建立在人為定義以後的,而實施“浏覽器劫持”的程式可以有很多,防不勝防。
為什麼說“浏覽器劫持”可以說是合法的呢?因為大部分浏覽器劫持的發起者,都是通過一種被稱為“BHO”(Browser Helper Object,浏覽器輔助對象)的技術手段植入系統的。
BHO是微軟早在1999年推出的作為浏覽器對第三方程式員開放互動接口的業界标準,它是一種可以讓程式員使用簡單代碼進入浏覽器領域的“互動接口”(INTERACTIVED Interface)。通過BHO接口,第三方程式員可以自己編寫代碼擷取浏覽器的一些行為(Action)和事件通知(Event),如“後退”、“前進”、“目前頁面”等,甚至可以擷取浏覽器的各個元件資訊,像菜單、工具欄、坐标等。由于BHO的互動特性,程式員還可以使用代碼去控制浏覽器的行為,比如常見的修改替換浏覽器工具欄、在浏覽器界面上添加自己的程式按鈕等操作,而這些操作都被視為“合法”的,這就是一切罪惡根源的開始。
BHO的出現幫助程式員更好的打造個性化浏覽器或者為自己的程式實作了友善簡潔的互動功能,可以說,如果沒有BHO接口的誕生,我們今天就不能用一些工具實作個性化IE的功能了。從某一方面來看,BHO的确是各種缤紛網絡互動功能的幕後功臣,但是一切事物都是有兩面性的,這個恒古不變的真理同樣對BHO有效,于是就有了今天讓安全界頭痛的“浏覽器劫持”的攻擊手段誕生。
看看前面我提到的BHO接口特性,你想到了什麼?BHO可以獲知和實作浏覽器的大部分事件和功能,也就是說,它可以利用少量的代碼控制浏覽器行為。程式員可以設計出一個BHO按鈕以實作使用者點選時通知浏覽器跳轉到某個頁面完成互動功能,當然就可以進一步寫出控制浏覽器跳轉到他想讓使用者去的頁面,這就是最初的“浏覽器劫持”的成因:BHO劫持。
在描述BHO劫持之前,我們先要對BHO接口的啟動做個簡單介紹:符合BHO接口标準的程式代碼被寫為DLL動态連結庫形式在系統資料庫裡注冊為COM對象,還要在BHO接口的系統資料庫入口處進行元件注冊,以後每次IE啟動時都會通過這裡描述的注冊資訊調用加載這個DLL檔案,而這個DLL檔案就是以成為IE的一個子產品(BHO元件),與IE共享一個運作周期,直到IE被關閉。
IE啟動時,會加載任何BHO元件,這些元件直接進入IE領域,而IE則成為它們的父程序和載體,從此IE的每一個事件都會通過IUnknown接口傳遞到BHO用以提供互動的IObjectWithSite接口裡,這是BHO實作與IE互動的入口函數。
BHO接收到IE接口傳遞來的參數後開始判斷IE正在做什麼,理論上BHO可以擷取IE的大部分事件,然後根據程式員編寫的代碼,BHO持有對特定事件做出反應的決定權,例如一個可以實作“中文網址”的BHO,就是通過GetSite方法擷取到IE目前打開的站點URL(或通過IURLSearchHook接口來獲知),如果BHO發現擷取到的URL和内置的判斷條件比對,該BHO就會啟用SetSite方法強制IE跳轉到程式員設定的頁面去,這個過程就是利用about:blank篡改首頁的“浏覽器劫持”方法之一,它的實作原理其實很簡單,程式員編寫一個惡意BHO元件,當它擷取到IE視窗的目前站點為“about:blank”時就強制IE内部跳轉到指定的廣告頁面,于是鬧出了不久之前沸沸揚揚的“IE空白頁劫持事件”。
了解了這種類似惡作劇的作案手段,要解決它就容易了,隻要找到并删除這個隐藏在系統裡的BHO程式即可。
除了這類“廣告軟體”性質的BHO,還有一種利用IURLSearchHook接口實作的另一類更隐蔽的BHO,這種BHO從某些方面來說大概不算BHO,因為它并不是響應IUnknown,而是等待IE建立IURLSearchHook來啟動。IURLSearchHook被浏覽器用來轉換一個未知的URL協定位址,當浏覽器企圖去打開一個未知協定的URL位址時,浏覽器首先嘗試從這個位址得到目前的協定,如果不成功,浏覽器将尋找系統裡所有注冊為“URL Search Hook”(資源搜尋鈎子,USH)的對象并把這個IE不能了解的位址發送過去,如果某個USH對象“認識”這個位址,它就傳回一個特定的辨別告訴IE它知道怎麼打開這個位址,然後IE就根據約定的方法調用它,最終打開這個位址。其實USH對象并不陌生,我們一些偷懶的使用者就經常為了省事而不輸入“http://”,但是IE最終還是能認出并打開某個位址,就是USH的功勞,但是這一點又被惡意程式員拿來磨刀了,通過建立自己的USH對象,惡意程式員能夠指令IE在找不到一些網站時自動跳轉到事先設定的站點裡,如果這個站點帶毒或者挂馬,使用者就完了。
這類BHO的解決方法和前面一樣,隻是它比較隐蔽,除非使用者經常偷懶,否則可能直到系統崩潰也不會知道自己已經感染了這種東西。也許你會說,隻要使用者的輸入永遠不會讓IE無法識别,這種滲透不就白費了?但是事實不容樂觀,我們無法得知BHO作者還會不會通過其他方法攔截IE,說不定每隔一段時間就讓IE彈出一個廣告呢?
上面說了這麼多BHO和IE合作搞破壞的事例,可能會給讀者造成一種“BHO必須在IE傳遞資料後才能行動”的誤解,然而事實并非如此,浏覽器自身也是一個标準的可執行程式,而BHO隻是借用這個程式程序啟動的DLL,它并非API那種要用的時候就讓你過來忙活,忙活完了就一腳踹開的奴隸形态DLL,前面說過了,BHO是一種在浏覽器加載時一同啟動的例程,它相當于一種自身運作邏輯不太明确的子程序(裡面都是對IE事件的響應和操作代碼),這個特性就造成了BHO DLL和API DLL本質的差別,BHO并不需要所有事件都必須依賴這個大家夥,它可以有自己決定的權利,隻要适當的修改,就能用BHO實作類似DLL木馬的功能,當然,這并不是說我們就能在IE眼皮下公然的肆無忌彈幹壞事的,由于BHO自身是作為IE子程序啟動的,它就必須受到一些限制,例如程式員不能在裡面自己建立網絡連接配接,這樣會導緻IE報錯崩潰并供出你寫的DLL,害怕BHO成為另一種後門的使用者可以松口氣了,要在BHO裡實作Winsock大概隻能在IE休息的時候才可以,但是會有哪個使用者開着個開空IE什麼事情都不做呢?
但這并不是說BHO就一定能無害了,雖然用它不能做到遠端控制,但是别忘記,BHO能看到IE的所有東西,也就能任意的通路使用者檔案和系統資料庫,在這個條件成立的前提下,入侵者可以編寫代碼查找使用者隐私,然後在适當時候通過SetSite送出出去——誰叫現在Webmail這麼流行呢?這就是為什麼許多廠商釋出諸如“中文網址”、“網絡搜尋”、“IE定制”、“IE監視”這些功能的BHO的同時都保證“不搜集使用者隐私”的原因,隻要你想要,BHO就能得到一切。
有些人也許會想,既然BHO是微軟浏覽器的權利,那我不用IE了,我用Opera、Firefox不行?對于這點固然無可厚非,但是你用不用Windows?用不用共享軟體?如果你用Windows,那麼,你仍然可能處于被BHO接觸到的世界,因為Windows本身就是和IE緊密結合的,這就把“IE程序”的範圍給擴大了,細心的使用者大概會發現,IE裡能直接通路“我的電腦”,“我的電腦”視窗也能迅速變成IE,因為它們實質都是依賴于IE核心的,正因為這個原因,BHO可以在你打開一個檔案夾時跟着偷偷啟動。同時,現在的網絡正處于一種“共享軟體捆綁戰略”大肆實施的時代,你再小心也不能避免某些共享軟體固定捆綁了BHO的行為,安裝後你才會發現檔案夾上又多了個什麼“助手”、“搜尋”了。要想徹底逃開BHO的圍困,大概隻能放棄使用Windows了。
三. Hook,你鈎住浏覽器了
“Life finds its way.”——《侏羅紀公園》
正如《侏》裡的這句話一樣,入侵者也在不斷尋找他們的新出路,雖然上面我說了這麼多BHO的負面事例,但是真正的危機并不是隻有BHO的,在一些使用BHO行不通的場合裡,入侵者開始投擲他們的鈎子。
什麼是鈎子?讓我們先看看它的官方定義:
鈎子(Hook),是Windows消息處理機制的一個平台,應用程式可以在上面設定子程以監視指定視窗的某種消息,而且所監視的視窗可以是其他程序所建立的。當消息到達後,在目标視窗處理函數之前處理它。鈎子機制允許應用程式截獲處理window消息或特定事件。
鈎子實際上是一個處理消息的程式段,通過系統調用,把它挂入系統。每當特定的消息發出,在沒有到達目的視窗前,鈎子程式就先捕獲該消息,亦即鈎子函數先得到控制權。這時鈎子函數即可以加工處理(改變)該消息,也可以不作處理而繼續傳遞該消息,還可以強制結束消息的傳遞。
可能上面的官方定義對一部分讀者了解有點困難,其實,鈎子就像是一切程式的“先知”,一個實作了鈎子的程式自身雖然也是普通程式,但是它總能在别的程式得到資料之前就已經知道了一切,這是為什麼呢?對Windows系統有一定了解的讀者應該知道,Windows系統是一個通過“資訊處理機制”運作的系統,在這個系統裡傳遞的資料都是通過“消息”(Message)的形式發送的,各個消息都遵循了官方的約定,否則就不能讓系統産生回應。而且這個傳遞步驟是颠倒的,例如我們關閉了某個程式,我們可能會認為是程式自己關閉後通知系統的,其實不然,當使用者點選關閉按鈕的時候,Windows就會把一個叫做WM_CLOSE的消息傳遞給這個程式,程式接收到消息後就執行解除安裝自身例程的操作。了解了這點,就能知道鈎子的原理了,所謂鈎子程式,就是利用了系統提供的Hook API,讓自己比每一個程式都提前接收到系統消息,然後做出處理,如果一個鈎子攔截了系統給某個程式的WM_CLOSE消息,那麼這個程式就會因為接收不到關閉消息而無法關閉自身。除了消息以外,鈎子還可以攔截API,像我們都熟悉的螢幕翻譯軟體就是Hook了一些文本輸出函數如TextOutA而達到了目的。
Hook技術讓程式設計人員可以輕松擷取其他程式的一些有用資料或傳遞相關資料,像現在常見的一些遊戲外挂,它們就是利用Hook技術鈎住了遊戲窗體,然後就可以識别遊戲裡面的行為和模拟發送按鍵滑鼠消息,最終實作電腦自己玩遊戲的功能。把這個技術應用到浏覽器上面,就成了另一種控制浏覽器行為的方法。
鈎子有兩種,本地鈎子(Local Hook)和全局鈎子(Global Hook),本地鈎子隻在本程序裡起作用,故不屬于讨論範圍;全局鈎子代碼必須以DLL形式編寫,以便在鈎子生效時被其它程序所加載調用,是以我們看到的大部分Hook程式都是DLL形式的。
其實之前提到的BHO也可以視為一種針對IE的鈎子,它鈎的是IE的事件,這就是IE與BHO互動的起點,但是對于再複雜一點的操作,例如判斷IE下載下傳的是GIF圖檔還是JPEG圖檔,BHO無能為力,因為它僅僅知道IE的事件為DownloadBegin和DownloadComplete,對于具體内容,IE本身是不會告訴它的,否則IE豈不是要忙死了?至少我也沒見過哪個上司還需要向秘書彙報中午吃了雞肉還是鴨肉的吧,BHO可不是IE的老婆,或者說IE沒有氣管炎。
是以,為了得到IE的更多資料,程式員開始鈎IE了。與BHO不同,鈎子不需要被動的等待IE事件,它直接和IE形成上司對下屬的關系,這次輪到IE要做什麼都得經過它準許了。Hook形式的控制不需要DLL檔案必須與IE的系統資料庫入口産生元件關系,它可以是一個獨立的DLL,通過Rundll32.exe或自帶的Loader EXE啟動,而且由于它屬于Hook形式, 在鈎子有效的情況下會被系統自動插入其他程式的程序中,是不是有點像DLL木馬呢?
IE鈎子程式載入程序後便能獲知所有的消息類型、API和内容,一旦發現某個符合要求的消息,如IE執行了某個事件,或者使用者輸入了特定内容,鈎子的處理代碼就開始工作了,它先攔截系統發送給IE的消息,然後分析消息内容,根據不同消息内容作出修改後再發給IE,就完成了一次Hook篡改過程。用著名的3721實名搜尋做例子,一些人會以為它是采用了BHO或者IURLSearchHook完成中文域名的識别跳轉的,其實它是用了能夠第一個得到Windows消息的Hook技術,這樣一來就可以避免被其他的競争對手搶先解析域名了:3721的主程式就是一個Hook DLL,它監視IE位址欄的消息,一旦使用者輸入的是中文,它便在其他BHO類插件工作之前攔截了這個消息,并調用自身代碼完成中文域名到英文URL的轉換工作,然後傳回(也可能與自己的BHO DLL配合)一個讓IE跳轉到英文URL的消息,完成域名的翻譯任務。
IE鈎子能幫助程式員用少量代碼完成更多的IE互動工作,但是一旦這個鈎子被用于犯罪,其後果也是嚴重的,惡意程式員可以寫一個攔截IE輸入的鍵盤鈎子,達到竊取密碼的作用,這樣無論你是用HTTP明文協定還是SecurityHTTP加密協定都不能逃避密碼被盜的下場了,因為它抓的是你在IE裡的輸入,後面的資料傳輸已經不重要了。
四. Winsock LSP
全稱為“Windows Socket Layered Service Provider”(分層服務提供商),這是Winsock 2.0才有的功能,它需要Winsock支援服務提供商接口(Service Provider Interface,SPI)才能實作,SPI是一種不能獨立工作的技術,它依賴于系統商已經存在的基本協定提供商,如TCP/IP協定等,在這些協定上派分出的子協定即為“分層協定”,如SSL等,它們必須通過一定的接口函數調用,LSP就是這些協定的接口。
通過LSP,我們可以比分析基本協定更簡單的得到我們想要的資料内容,如直接得到系統上運作的浏覽器目前正在進行傳輸的位址和内容,不管這個浏覽器是IE,還是Opera或Firefox,因為LSP是直接從Winsock擷取資訊的,即使不用微軟生産的汽車,至少你這輛汽車一直是在微軟建造的公路上跑的吧。
LSP用在正途上可以友善程式員們編寫監視系統網絡通訊情況的Sniffer,可是現在常見的LSP都被用于浏覽器劫持,使使用者又多了個噩夢。
五. 亡羊補牢,還是居安思危?
也許大部分家庭使用者都是在經曆過一次入侵或中毒事件後才知道安全防範的重要性的,能亡羊補牢當然是好事,但是如果能對自己的要求提高一點,做到未雨綢缪豈不是更好?我們總是依賴于别人的技術,依賴于模式化的殺毒手段,但那些始終都是别人的東西,控制權不能掌握在自己手上,這并不是很好的事情,也許,該是暫時放棄遊戲挂級、搜集明星電影,好好研讀一下安全方面和系統原理書籍的時候了,否則在這個不安全的網絡中,我們随時可能會迷失自己。
可能有人會想,小金又在發感慨了。也許是的,因為清除“浏覽器劫持”一般都需要手工進行,雖然現在已經有了多個檢測浏覽器劫持的工具如HijackThis、Browser Hijack Recover等軟體面世,但是如果你抱着和以往使用殺毒工具那樣“一開掃描就安枕無憂”想法的話,你會發現自己真的會迷失了,由于BHO的特殊性(别忘記,它是合法的),這些工具隻會把系統的程序、BHO項目、啟動項、LSP等需要有一定技術基礎方能了解的東西顯示給你,然後由你自己決定IE的明天,如果你不曾重視過安全技術,那麼就會覺得這些工具如同另一種折磨你的病毒了。
學,還是不學?這是個必須考慮的問題……