第一章 緒論
1.2 相關緩衝區溢位防禦工具探討
既然緩衝區溢位漏洞是一個嚴重的問題,許多解決方法已被提出來處 理這個問題。
1.2.1 原始程式碼分析技術
這類技術[11][24][34][18][10][9]試著去分析程式碼找出可能漏洞的所 在,產生警告告知程式設計師以修改成正確的程式碼。然而目前的研究結 果並不佳,經常會產生相當大量不正確的警告。一些研究試著在原來的程 式碼分析技術上結合執行期(runtime)存取動作的檢查,例如 CCured[20]或 Cyclone[14],它將靜態分析階段較難判定的程式碼片段,在執行時期進行 複查的動作,如此改善了誤報率且不會造成程式碼太大負擔。
由於這類技術必須要能得到原始程式碼,因此只能應用在程式發展階 段,對於現存的一些已部署的應用程式無法立即提供防禦。
1.2.2 執行期溢位偵測技術
這類技術是在編譯前或編譯時插入保護程式碼或是直接修改可執行 檔,當執行時所插入的保護程式碼會偵測出溢位存取。目前這種技術依保 護的方法可分為下面幾類:
1. 不可執行的區塊:由於緩衝區溢位攻擊通常會在去執行存放在記憶 體中的惡意程式碼,透過限制記憶體區塊的執行權限以防止溢位攻 擊成功。例如Non-executable Stack[29]、Non-executable Heap[21]。
2. 間隔:因為緩衝區溢位會通常會連續的存取記憶體,所以可在緩衝 區與其他資料或其他緩衝區中插入一段空間,當該空間被存取即可 得知溢位。若該空間被存取時馬上能得知稱為強制性間隔(strong separation),例如 ElectricFence[22];若該空間被存取一段時間後才 能得知稱為被動性間隔(weak separation)。例如 StackGuard[7]。
3. 確保完整性:因為緩衝區溢位會覆寫掉其他資料,所以此技術去檢 查其他資料的是否與原先一致以測知溢位是否發生,或是透過加解 密資料使其完整性不被破壞。例如Libverify[3]、StackShield[33]、
PointGuard[6]。
4. 邊界檢查:檢查是否超出緩衝區的邊界。例如 BCC(Bounds-Checking C) [16]、CASH(Checking Array Bound Violation Using Segmentation Hardware) [17]、CRED(C Range Error Detector) [25]、Libsafe[3]、
J&K(Jones and Kelly checker) [15]。
表1-3 一些執行期溢位保護機制的比較 Kernel patch
Stack buffers Non-executable
Stack
No Runtime instrument
Heap buffers ElectricFence
No Recompile programs
All pointers PointGuard
Yes Recompile programs
All buffers BMB
No Recompile programs
All buffers CRED
No Runtime instrument
Return addresses Libverify
No Recompile programs
Return addresses StackGuard Kernel patch
Stack buffers Non-executable
Stack
No Runtime instrument
Heap buffers ElectricFence
No Recompile programs
All pointers PointGuard
Yes Recompile programs
All buffers BMB
No Recompile programs
All buffers CRED
No Runtime instrument
Return addresses Libverify
No Recompile programs
Return addresses StackGuard
支援的保護機制;另一個原因是只保護與程式執行相關的資料,例如回傳 位址與函式指標,導致其防禦的範圍不夠廣,只能解決部份的緩衝區溢位 問題。
第四類根據檢查記憶體存取動作的範圍決定防禦的範圍,但普遍有範 圍越廣效能越差的問題。根據麻省理工學院的Lincoln 實驗室評估[23],
CRED 是目前防禦範圍最廣的偵測工具。它修改了編譯器,當程式每次要 存取緩衝區的資料時,插入檢查程式碼,檢查該存取動作是否超出緩衝區 的邊界。然而C/C++並未定義緩衝區長度資訊,故需以某種資料結構維護 緩衝區長度資訊。資料結構的操作卻造成了效能的低落。因為溢位存取發 生次數的相比於正常的緩衝區存取仍屬於極少數,且執行期偵測機制主要 是用以防止隱性的漏洞,為了不知道是否發生的溢位問題,如此犧牲效率 的代價太大。
1.2.3 執行期溢位恢復技術
前一小節所提的執行期偵測技術在受到偵測到攻擊時,多半直接終止 受害的程式,此舉確實能防止程式不受緩衝區溢位攻擊的進一步傷害,但 卻會衍生另一個問題。例如服務程式(servers or daemons)一旦受到攻擊而被 保護機制終止,就另一種方面來說攻擊者已達到了利用緩衝區漏洞造成阻 斷服務(denial of service)的目的。因此使程式從緩衝區溢位中恢復,儘可能 持續維持程式執行成為新的研究方向。
Execution Transaction[28]以類似資料庫處理的方式來恢復溢位問題。這 個機制將每個函式視為一個處理單位(transaction),若該函式中的緩衝區存 取發生溢位,則中斷(abort)該函式並且跳回上一層函式繼續執行。但該研究 中做了許多的C/C++語意上的假設,因此實際上是否可行仍待評估。
BMB(Boundless Memory Blocks) [23]是另ㄧ個恢復機制。其基本的想法 是因為緩衝區有大小限制,所以造成了緩衝區溢位,若緩衝區無限大就不 會有緩衝區溢位發生。它以CRED 為基礎,檢查每次緩衝區存取,若溢位 發生,則配置ㄧ個新的記憶體區塊,並將溢位存取導向到新的記憶體區塊,
之後再恢復程式執行,如此溢位存取就無法覆蓋到其他記憶體中的資料,
而且程式仍能繼續執行。這個技術最大的缺點是繼承了CRED 的嚴重效能 負擔。
1.2.4 資料位址混亂技術(Obfuscation)
由於相同的程式在相同的作業系統上的記憶體配置方式相同並且有一 定的規律,通常利用溢位漏洞的攻擊者能夠透過模擬或或計算出需要覆蓋 資料的位址。所以有研究[21][5]利用隨機改變資料配置位址來防堵攻擊者 達到目的。這類技術配置的原則有三種:1. 隨機改變記憶體區塊起始位址;
2. 改變資料配置的高低位址順序;3. 各個區塊間會有任意大小的間隔。
此類技術造成的效能負擔相當低,程式變動也不大,確實可利用相當 低的攻擊成功機率來退卻想嘗試攻擊的惡意破壞者。但是這個機率卻無法 達到像密碼學所要求的那麼低,有耐心的攻擊者仍可在一段時間後成功的 攻擊。