見招拆招 改裝Apache就地抵禦DoS攻擊

根據統計,目前以Apache伺服器架設網站伺服器的網站數目已遠超過利用微軟IIS架設網站伺服器的數量。因此,Apache伺服器一直都是駭客心目中顯著的目標。本文將示範如何利用強大的mod_rewrite模組來強化Apache伺服器的防禦能力,讓可怕的DoS攻擊消弭於無形。

2011年8月,一個知名的資安論壇發表了一篇攻擊Apache伺服器的攻擊手法文章(稱為Apache Killer),此攻擊手法不但可以用簡單的方法來癱瘓Apache伺服器的服務,即所謂的拒絕服務攻擊(Denial of Service,DoS),而且影響範圍涵蓋目前大部分Apache的版本,而使得大部分使用Apache的網站伺服器均陷入危險當中,也迫使Apache開發團隊在短時間內即推出修正的版本。目前依官方網站的說明指出,在Apache 2.2.20以上的版本已修正此漏洞。

如果要預防此類的攻擊,最根本的方式即是直接將Apache伺服器更新到2.2.20版,但在實務面上,要更換原先服務的網站伺服器並不是一件簡單的事。

因此在本篇文章中,筆者將簡單說明Apache Killer攻擊原理,並搭配mod_rewrite模組來實作一個能預防Apache Killer攻擊的網站伺服器(在本文中,筆者所使用的網站伺服器版本為Apache 2.0.64)。

剖析HTTP運作原理

HTTP全名為Hypertext Transfer Protocol(超連結通訊協定)。這是用來定義網際網路上資料傳輸的通訊協定。主要的用途在於接收與解譯HTML網頁。簡單的HTTP通訊協定即是一種傳送與回應的機制,其步驟如下:

1. 使用者傳送HTTP要求(Request)給網站伺服器。
2. 網站伺服器接收到這個要求後,經過處理再回應(Response)給使用者

而在上述中的Request要求即是使用者端利用HTTP Request來請求網站伺服器服務,網站伺服器在取得此HTTP Request要求(此要求即包含使用者端的瀏覽器,欲瀏覽的頁面及請求服務的伺服器等等資訊)。在處理完畢後,即利用HTTP Response封包(此回覆封包將包含使用者所請求的頁面及狀態等等相關資訊)回覆給使用者。

上述的Request封包內容分為表頭欄位(Header)及內容欄位,其中表頭欄位是用來說明此HTTP封包的狀態情況。表1說明了Request要求封包中的表頭欄位相關資訊。

表1 Request封包內表頭欄位相關資訊一覽表

在簡單說明Request要求封包的欄位後,接下來說明Response要求封包的欄位,如表2所示。

表2 Response要求封包欄位相關資訊說明

在開源碼社群中,其實也有一些不錯的工具可用來查看HTTP封包內容,如Fidder等,但最簡單的還是利用telnet查看來往的HTTP封包資訊。

何謂拒絕服務攻擊

在一般駭客攻擊的目的不外乎「窺探」與「控制」,利用木馬病毒常駐於受害主機上,伺機竊取主機上的帳號、密碼等資訊,或開啟後門等待駭客連線來控制受害主機,而拒絕服務攻擊(DoS)卻不是為了上述的目的。它僅是為了癱瘓受害主機,使其停止服務。拒絕服務攻擊通常利用下列的原理進行攻擊。

利用程式漏洞進行攻擊

利用程式漏洞來造成緩衝器溢位(Buffer Overflow),使得服務程式停止,進而停止服務。所謂的緩衝區溢位,指的是當程式執行時會在系統記憶體上存放下列的結構。由低位址的空間往高位址空間儲存,在邏輯上可分為程式邏輯(Code/Text)區、資料(Data)區、堆疊(Stack)區:

程式邏輯區:在此區中存放的是執行程式碼(如程式邏輯等)。

資料區:在此區中存放的是程式內所宣告的變數,如以C語言為例,宣告「char buf[32] /*」,即是宣告一個名稱為buf的變數,此變數即會存放在資料區。

堆疊區:在此區中存放的是程式重要的參數,其中最重要的為EIP暫存器(又稱為程式指示器)。EIP暫存器中存放的是「返回位址」,可以將它視為執行下一個指令的位址,這也是緩衝區溢位攻擊是否能成功的關鍵。

以上述buf[32]為例,如果程式未檢查陣列buf的邊界值。一旦攻擊者傳入大量的字串(超過32位元組)給buf變數,資料區的資料即會滿溢而覆蓋掉堆疊區的資料(其中包括EIP暫存器的值),如右圖示。

所造成的後果,輕則程式當掉,因為EIP值被覆蓋成無意義的位址,造成程式無法正確地往下執行,重則程式會執行攻擊者的惡意程式。如果計算精準的話,EIP會被覆蓋成惡意程式的入口位址,而使得程式在返回時去執行惡意程式。

就像程式會轉彎一樣,預防緩衝區溢位的方式,根本的方式是在設計時要靠嚴謹地驗證輸入欄位的型態及長度來解決。另一種則是依賴編譯器(Compiler)的幫忙,在編譯階段即藉由邊界值的檢查來發現可能會造成緩衝區溢位的程式碼。

利用通訊協定漏洞進行攻擊

由於TCP/IP通訊協定先天上設計的漏洞,常使有心的攻擊者能夠利用相關的漏洞來實施拒絕服務的攻擊,常見的攻擊手法如TearDrop、Land或smurf(就是有名的卡通「藍色小精靈」的原文)等知名攻擊手法。接下來,說明Apache Killer的攻擊原理。

就如同上一個章節在HTTP運作原理中所述,HTTP通訊協定是使用者發出一個HTTP要求訊息給網站伺服器。網站伺服器接收到使用者的要求,在進行處理後,再以HTTP回覆訊息回應給使用者,而Apache Killer的原理即是利用HTTP要求訊息中標頭欄位的Rang欄位處理。Rang欄位是記錄要求網站伺服器回傳要求網頁中的某個範圍內容,例如僅傳送網頁資料中的第10個字元至第20個字元等等。

在一般預設情況下,若沒有指定Rang欄位,當碰到一個HTTP要求,網站伺服器會回覆一整個網頁,系統也僅消耗掉一份資源。

但如果惡意的使用者故意發送一個指定傳送多個範圍的Rang資訊(如設定「Range: bytes=1000-2000,1000-2001?」,表示此一HTTP要求請求網站伺服器回傳網頁第1000至2000及1000至2001??範圍的網頁資訊),網站伺服器為了處理此要求,所消耗的系統資源將倍數於正常未設定Ranger的要求,因而消耗了網站伺服器所在的主機系統資源。等到資源耗盡,網站伺服器即停止服務,進而達到拒絕服務攻擊的目的。

接著,以如下的測試環境為例進行示範說明(以VMware建構測試系統):

作業系統:FC 15
記憶體:512M
Apache版本:2.0.64

利用Apache Killer的攻擊程式進行測試。讀者可至Google以「Apache Killer」為關鍵字查詢,即可找到相關的攻擊程式碼。在此,僅使用一台主機當作攻擊主機,攻擊不需要10分鐘,就會讓系統產生「Out of memory」錯誤,而使得整個主機無法使用,如下圖示。

接下來,可利用telnet指令實際體會整個HTTP通訊協定(有Range與無Range的差別)的存取,請執行下列指令:

網站伺服器即會回覆整個網頁,類似的情況就如下圖所示。

然後,再來看看如果在HTTP要求加上Range欄位,網站伺服器會如何回應要求,此時執行如下的指令:

如下圖所示,可以發現網站伺服器會根據HTTP要求中的Range回覆多個部分網頁內容。這也就意謂著,在預設的情況下,一個HTTP要求僅消耗掉系統一份資源。

但如果有心人士送出一個含有Range欄位資訊的惡意HTTP要求,就會讓網站伺服器重複消耗掉多份的系統資源。 Apache Killer攻擊法即是根據此項原理來實作拒絕服務攻擊,它在一個HTTP Request封包中的表頭上加入Range資訊,而網站伺服器就必須消耗過多的資源來處理此HTTP要求。

如何防治Apache Killer

在了解Apache Killer的攻擊原理後,要防止此類攻擊的預防,最直覺的想法是解析來往的HTTP要求封包,若發現封包內有Range的欄位資訊,就直接改寫Rang資訊,以避免Apache Killer的攻擊。

在Apache的官方模組中即提供一個類似功能的模組(mod_rewrite),簡單的說,mod_rewrite就是一個可監控並改寫來往HTTP封包的模組,也因此可利用此模組來改寫或過濾含有Rang欄位的HTTP要求封包。接下來說明mod_rewrite模組的安裝方式,其安裝方式有內建模式和以DSO編譯模式兩種。

內建模式

當編譯Apache原始碼,在執行組態(Configure)時加上「--enable-rewrite」參數來內建mod_rewrite模組。可以利用「httpd -l」指令來查看Apache伺服器是否內建mod_rewrite。如果有mod_rewrite,即表示已內建mod_rewrite模組。

以DSO編譯模式

由於,一般Apache預設是不會將mod_rewrite模組編譯進來,因此在本文中,將採用DSO動態編譯模組的方式讓Apache伺服器支援mod_rewrite。

首先,須下載符合系統內版本的Apache伺服器原始碼(以筆者為例,所使用的版本為2.0.64,因此下載版本為2.0.64的原始碼)。下載完成後,在該原始碼目錄找到mod_rewrite.c所在的目錄(例如「/modules/mappers/」),並切至該目錄下,以及執行下列指令:

在編譯完成後,可在「/usr/local/apache2/modules」目錄內發現mod_rewrite.so檔案(這是因為筆者將Apache安裝在「/usr/local/apache2」目錄下)。若要使用此模組,還必須在httpd.conf檔案內加入下列幾行設定:

隨後,重新啟動Apache伺服器即可。接下來,繼續說明mod_rewrite模組所提供的參數說明。表3為常用的mod_rewrite模組參數。

表3 常用的mod_rewrite模組參數

表3所說明的相關參數,僅是本次預防Apache Killer需要使用到的參數,事實上,mod_rewrite模組的功能相當強大,但限於篇幅,就不多做介紹了。

如同上文所述,Apache Killer的攻擊原理在於利用HTTP通訊協定中的Range欄位,因此若能將含有惡意HTTP要求封包中的Range欄位置換掉,即可防此類攻擊。可以利用mod_rewrite模組來達到此類要求。請將下列設定字串加入httpd.conf組態檔中。

在設定完成後,重新啟動Apache伺服器,再利用網路上流傳的Apache Killer攻擊程式來測試。將會發現Apache伺服器再也不會受到此類攻擊的影響。

此外,可以到「/var/log/rewrite.log」查看相關的mod_rewrite模組Log。在如下圖中所示的Log資訊中,即表示mod_rewrite模組已經將含有Rang欄位的資料置換掉了。

至此,一個可防止Apache Killer攻擊的網站伺服器就建構完成了!


追蹤我們Featrue us

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!