網頁***與漏洞


    網頁***正是由於漏洞的存在,才得以不斷繁衍。現在網頁***所利用的漏洞主要有兩類:一類是邏輯型漏洞,另一類則是溢出型漏洞。邏輯型漏洞的數量比較少,通常都是由利用系統本身提供的一些功能來完成***的下載和執行的;而溢出型漏洞則是利用程序編寫中的一些漏洞來獲得瀏覽器的控制權。兩者在利用手段上有本質的不同。在本章中,筆者將對兩種漏洞分別舉例進行說明。
2.2.1 邏輯型漏洞
    BMP網頁***是早期比較典型的網頁***之一,利用的就是邏輯方面的漏洞。它先把一個EXE文件僞裝成一個BMP圖片文件,欺騙IE自動下載,再利用網頁中的JAVASCRIPT腳本查找客戶端的Internet臨時文件夾,找到下載後的BMP文件,把它複製到TEMP目錄,再編寫一個腳本把找到的BMP文件用DEBUG還原成EXE,並把它放到註冊表啓動項中,在下一次開機時自啓動。我們可以看到,在這個過程中,全都是利用Windows系統提供的函數和接口,漏洞就在於早期版本的IE瀏覽器在Internet域下仍允許Javascript腳本讀寫本地文件和修改註冊表,被惡意的***利用製作網頁***。新版本的IE便修補了這個邏輯漏洞,只有在我的電腦域下IE瀏覽器纔有權限執行上述惡意腳本代碼。
    2001年,再次發現微軟的IE瀏覽器存在重大的安全缺陷。簡單地說,IE在處理MIME頭中"Content-Type:"處指定的某些類型時,存在問題,***者可以利用這類缺陷在IE客戶端執行任意命令。這個漏洞也是一個典型的邏輯方面的漏洞,IE瀏覽器在遇到如下EML文件時:
Content-Type: audio/x-wav;
name="hello.bat"
Content-Transfer-Encoding: quoted-printable
Content-ID: <THE-CID>
echo OFF
dir *.*
    儘管該附近被聲明爲audio/x-wav類型,但是IE或者Outlook瀏覽器會執行hello.bat這個腳本。這兩個漏洞是比較早期的漏洞,都是針對IE5.5、5.0的,感興趣的讀者可以找一臺Windows98或者Windows 2000sp0的機器測試一下,自從IE6推出以後這樣的漏洞幾乎就絕跡了。
    百度是我國最大的搜索引擎供應商,2007年7月份爆出的百度超級搜霸BaiduBar.dll ActiveX控件遠程代碼執行漏洞也是一個邏輯漏洞,同樣是利用了IE這個***平臺,不過漏洞不是IE或者Windows系統造成的,而是百度搜霸造成的。漏洞存在於由ActiveX控件"BaiduBar.dll"導出的"DloadDS()"函數中,相關信息如下:
InprocServer32: C:\Program Files\baidu\bar\BaiduBar.dll
ClassID : A7F05EE4-0426-454F-8013-C41E3596E9E9
[id(0x0000001d), helpstring("method DloadDS")]
void DloadDS(
[in] BSTR bstrUrl,
[in] BSTR bstrName,
[in] long lShow);
    如果把bstrUrl設置成某個服務器上的CAB文件,DloadDS()函數會嘗試將這個文件下載到TEMP目錄並解壓,然後執行其中以bstrName命名的文件,由於在這以前沒有任何有效的檢查措施,因此***者可構造包含***或者間諜程序的CAB文件,然後用DloadDS()函數下載並運行它。因此,有漏洞的百度搜霸相當於一個完美的後門。
同樣爆出漏洞的還有Web迅雷,Web訊雷組件的名稱:ThunderServer.webThunder.1,可以採用JS代碼new ActiveXObject("ThunderServer.webThunder.1");來激活訊雷的組件。其中的關鍵函數包括:
SetBrowserWindowData:新建瀏覽器窗口;
SetConfig:設置Web訊雷;
HideBrowserWindow:隱藏瀏覽器;
AddTask:添加下載任務;
SearchTask:搜索任務,得到任務ID,文件下載狀態等詳情;
OpenFile:根據任務ID,打開文件。
    ***者利用這一系列的函數,現已經能完成從下載到運行***程序的完整過程,實現了一個完整的網頁***功能。這個Web迅雷漏洞的曝光時間是2007年6月。
    類似的邏輯漏洞還不少,這裏就不一一列舉了,邏輯漏洞主要是由於程序員毫無安全意識造成的,屬於很低級的錯誤。儘管IE瀏覽器本身逐漸已經沒有這樣的漏洞了,但很多第三方的ActiveX控件還存在很多的安全隱患。由於決定木桶盛水量多少的是最短的那塊木板,而不是最長的那塊;故信息安全也應遵循這個木桶原理。
2.2.2 溢出型漏洞
    相對於邏輯型的漏洞,溢出型漏洞的數量就要多得多。這裏所說的溢出型漏洞是指利用緩衝區溢出來傳播***病毒的網頁***,鑑於目前國內網絡安全的嚴峻現狀,由於微軟對IE瀏覽器的漏洞修補都比較及時,故大部分網頁***都已經開始轉而利用一些國產軟件的漏洞來***用戶。關於緩衝區溢出,筆者在第4章中將會詳細介紹。這裏先介紹溢出型網馬所要用到的一些技術,主要有:ActiveX技術、Shellcode技術、HeapSpray技術。
2.2.3 關於ActiveX
    ActiveX是Microsoft公司提出的一組使用COM(Component Object Model,部件對象模型)使得軟件部件在網絡環境中進行交互的技術集。它與具體的編程語言無關。作爲針對Internet應用開發的技術,ActiveX被廣泛應用於Web服務器以及客戶端的各個方面。同時,ActiveX技術也被用於創建普通的桌面應用程序。ActiveX控制是OLE控制的更新版本。控制(Control)是建立可編程部件(Component)的主要元素,ActiveX控制可以用於所有支持COM規範的容器中,或者作爲Internet控制嵌入到Web頁面中。用戶訪問該頁面時,將下載該控制並自動地在本地註冊。利用腳本描述語言(Script)可以在控制之間以及客戶與服務器之間通過設置屬性(Property)、調用方法(Method)和激活事件(Event)進行通信。ActiveX控制與以前的OLE控制相比,具有更少的接口,並且可以沒有窗口。
    所有的ActiveX控制都支持IUnknown接口。目前,很多第三方開發商都編制了各式各樣的ActiveX控制。在Internet上,有超過1000個ActiveX控制供用戶下載使用。在Windows的SYSTEM目錄下,保存有很多Windows提供的ActiveX控制。Microsoft Visual C++(以下簡稱VC)提供的MFC(Microsoft Foundation Classes)控制都是ActiveX控制。利用VBScript或者Microsoft JScript,可以向Web頁面中加入可用於交互的ActiveX控制,將數據預處理或者檢驗過程放在客戶端進行,然後將結果傳往Web服務器。在一個Web頁面中引入ActiveX控件的方法主要有兩種:
    *通過Object標籤:<object id="gl" classid="clsid:F3E70CEA-956E-49CC-B444-
73AFE593AD7F"></object>
    *利用JavaScript中的New方法:new ActiveXObject("ThunderServer.webThunder.1")
2.2.4 關於Shellcode
    Shellcode這個概念是隨着緩衝區溢出而產生的。從概念上來說,Shellcode是一段用來***軟件Bug的可重定向的機器碼,之所以被叫做Shellcode是因爲在早期這一小段機器碼都用於啓動一個命令行的Shell以便控制肉雞,但是後來由於Shellcode並不僅僅用於得到一個Shell,還能完成很多其他的功能,例如:下載並執行***、添加一個用戶等,所以有人覺得Shellcode這個名詞的範圍有點小,但是其他名詞也得不到大衆的普遍認可。
    Shellcode存在於一個進程的內存中,在***者通過棧溢出、堆溢出、或格式化字符串等漏洞獲得執行權以後用來完成某一特定功能的一段代碼,獲得執行權的方法隨着系統架構的不同而有所不同,在我們所熟悉的Windows系統下,通常是通過覆蓋棧中的返回地址或異常處理例程的地址來獲得EIP的控制權的。關於緩衝區溢出,筆者在第4章中將會進行詳細介紹。
2.2.5 關於Heap Spray
    這種方法最早是由荷蘭***Berend-Jan Wever創造的,究竟什麼是Heap Spray呢?僅僅從字面上來理解,就是“堆的擴展”。這一技術用JavaScript腳本創建了很多個String對象,在String對象中寫入一個長長的NOP鏈以及緊接着NOP鏈的一小段Shellcode。JavaScript的動態運行庫會把這些String對象都存儲在堆中。由於堆中的數據是不斷向內存高址增長的,在大約分配了200MB的內存給這些string對象之後,在50MB~200MB這段內存中,隨意取出一個地址,便極有可能落在nop+Shellcode的中間。把某個返回地址覆蓋掉,變成這個隨意取出的地址之後,我們就能跳到這個NOP鏈上,最終執行Shellcode。
    使用這種方法有兩方面的優點,由於新版本IE瀏覽器的許多Dll都是使用VS7以上版本編譯的,VS7提供了一個新的編譯選項/GS用於防範緩衝區溢出問題,如圖2.7所示。
圖2.7  Visual Studio中的/GS選項
    /GS選項檢測改寫返回地址的某些緩衝區溢出,這是一種利用不強制緩衝區大小限制的代碼的常用技術。這是通過將安全檢查插入到已編譯代碼中完成的。/GS只嘗試檢測進入返回地址的直接緩衝區溢出。
    通過將函數調用的返回地址傳遞到堆棧上的調用約定,可以很容易地在計算機上利用緩衝區溢出。例如,x86使用將函數調用的返回地址傳遞到堆棧上的調用約定。
    對於編譯器認爲容易出現緩衝區溢出問題的函數,編譯器將在堆棧上返回地址之前分配空間。在進入函數時,用安全Cookie(它在模塊加載時計算一次)加載分配的空間。然後在退出函數時,調用編譯器幫助器以確保Cookie值仍然不變。如果該值發生變化,則可能已經改寫返回地址,因此將報告錯誤並且終止此進程。除非已用_set_security_error_handler提供了備用處理程序,否則將出現警告用戶存在潛在安全問題的消息框並調用ExitProcess。
    當靜態鏈接到CRT時,每個程序映像將具有自己的處理程序。當使用動態鏈接時,每個組件將共享公共處理程序。/GS需要CRT啓動代碼,故當用/GS編譯DLL時將引出問題。安全Cookie的預期值由CRT在CRT_INIT函數中重置。如果函數是用/GS編譯(因此具有安全Cookie)的,而它又調用CRT_INIT,則預期的安全Cookie值將更改,並且程序將認爲已出現緩衝區溢出。解決方案有如下兩個:
    1.不要在調用(或結束調用)CRT_INIT的任何函數中使用數組,例如,改用_alloca;
    2.使CRT正常初始化。不要指定自己的入口點,請改用DllMain(並且不要調用CRT_INIT)。/clr不支持/GS。
    /GS不能抵禦所有緩衝區溢出安全***。例如,通過改寫到參數區域來進行緩衝區溢出***仍然是有可能的。因此,即使您使用/GS,也應儘量編寫安全的代碼;也就是說,確保代碼沒有任何緩衝區溢出。/GS可以保護您的應用程序,不會發生代碼中確實存在的緩衝區溢出。
    對於棧溢出,/GS選項的保護非常有效,它能夠有效檢測返回地址是不是被覆蓋。但是對於IE瀏覽器裏發生的溢出,就有可能被繞過,用的正是Heap spray技術。***者首先執行的就是以下這段javascript腳本,將堆填充成大量NOP+Shellcode的形式到0x05050505這個地址。然後在存在棧溢出的函數中構造0x05050505形成的超長字符串覆蓋整個堆棧段,在往外覆蓋的時候由於觸發了寫入異常,流程轉入了SEH處理。由於整個堆棧都被0x05050505覆蓋,而恰恰異常處理的地址就是存放在堆棧中的,所以EIP就會轉向0x05050505,在執行了一系列nop以後,最終Shellcode將獲得執行權。
<SCRIPT language="javascript">
var heapSprayToAddress = 0x05050505;
//填充最簡單的死循環Shellcode
var payLoadCode = unescape("%uFEEB%uFEEB%uFEEB");
//申請每個堆塊的大小,確保塊和塊直接無縫鏈接
var heapBlockSize = 0x400000;
var payLoadSize = payLoadCode.length * 2;
var spraySlideSize = heapBlockSize - (payLoadSize+0x38);
var spraySlide = unescape("%u9090%u9090");
spraySlide = getSpraySlide(spraySlide,spraySlideSize);
heapBlocks = (heapSprayToAddress - 0x400000)/heapBlockSize;
//利用new方法從堆中分配內存
memory = new Array();
for (i=0;i<heapBlocks;i++)
{
memory[i] = spraySlide + payLoadCode;
}
function getSpraySlide(spraySlide, spraySlideSize)
{
while (spraySlide.length*2<spraySlideSize)
{
spraySlide += spraySlide;
}
spraySlide = spraySlide.substring(0,spraySlideSize/2);
return spraySlide;
}
</script>
    將上述腳本保存爲HTML執行以後,筆者的計算機的PF使用率迅速升高,使用調試器OD附加到IE瀏覽器的進程,可以發現0x05050505地址已經被NOP+Shellcode形式的長字符串覆蓋,如圖2.8和圖2.9所示。
圖2.8 堆擴展會大量消耗內存
圖2.9  JS已經成功進行堆擴展
    使用堆擴展技術的exploit有一個非常顯著的缺點,就是會耗費大量內存;在配置稍低的計算機上將使IE和整個系統的速度顯著變慢,甚至使IE瀏覽器處於假死狀態。在這個例子中,擴展到0x05050505就耗費了近200MB內存,假如要擴展到0x0F0F0F0F,那麼吃掉的內存會更加的驚人!恐怕還沒有等到內存分配完,瀏覽器已經被等得不耐煩的用戶給關閉了。
    堆擴展技術的另外一個缺點就是成功率不穩定。在本例中,由於整個過程我們只打開了一個網頁,所以能夠成功地將堆擴展到0x05050505。但是如果用戶打開過數個大型Web頁,裏面有很多不同類型的對象,也許堆地址早已分配到0x06060606了,那麼這次***肯定失敗。
    堆擴展技術的這個缺點同時也是一個優點,因爲只要把地址設得高一點,就幾乎不會已經被佔用了。而這種方法恰恰可以彌補通用性不強的缺點,本來覆蓋返回地址針對不同的IE版本、不同的Windows系統需要使用不同的跳轉地址;但是堆擴展技術彌補了這個缺點,一個地址就能做到通用。
 
本文節選自電子工業出版社2009年5月出版的《網頁******實戰》一書。
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章