論文閱讀:Automatic Generation of Data-Oriented Exploits

2020-08-09 13:52:13

論文題目:Automatic Generation of Data-Oriented Exploits
這篇論文來自於Usenix 2015

簡介:

由於針對控制流劫持的防禦機制 機製在廣泛應用,控制流導向的漏洞利用變得更加複雜了。一個備選方案是,針對非控制數據進行攻擊,就無需轉移控制流。雖然數據流攻擊可以造成嚴重的危害,但是目前沒有系統自動化構建它們的方法。作者設計了一種新的技術叫data-flow stitching, 可以系統地去找程式中的數據流來生成數據流利用。作者構建了一個工具叫FLOWSTITCH,可以在linux和windows的二進制檔案上執行。在實驗中,發現FLOWSTITCH可以在8個真實有漏洞應用中,自動化構建16種未知和3種已知的數據流攻擊。所有的利用都考慮細粒度的CFI和DEP,其中10個也考慮了ASLR。構建的利用可以造成嚴重的危害,比如敏感資訊泄露,提權。

背景

研究意義

在記憶體錯誤利用上,攻擊者經常去實現任意程式碼執行,而這通常是終極目標。這些攻擊通常通過利用記憶體錯誤來劫持程式控制流。然而這種基於控制流的攻擊,包括程式碼注入和程式碼複用,可以被CFI,DEP,ASLR等防禦機制 機製所阻擋。最近這些機制 機製得到了廣泛的認可,並被應用到一些操作系統,編譯器等地方,使得基於控制流的攻擊更難了。

然而,控制流攻擊並不是唯一的記憶體利用方式。記憶體錯誤同樣可以通過污染非控制數據來實現數據流攻擊。數據流攻擊可以破壞程式的數據或者泄露關鍵數據。心臟滴血漏洞就是一個敏感數據泄露,而控制流沒有改變的例子。

雖然數據流攻擊理論上很簡單,但是實際上的數據流攻擊都只是破壞非控制數據。目前沒有系統的方法來識別和構建數據流攻擊。

關鍵技術和挑戰

關鍵思路是如何高效搜尋一條新的數據流邊,並且加入到G‘中,從而在vs和vt間建立數據流路徑。

Challenge1:搜尋空間很大。一個2D-DFG中有很多數據流和一大堆節點。比如,在SSHD攻擊中有776源節點和56個目標節點。由於我們經常需要分析去連線每對節點,因此尋找一條可行路徑的搜尋空間是巨大的。

Challenge2:對於記憶體佈局知之甚少。大多數現代的操作系統預設開啓ASLR。數據記憶體區域的及地址,比如棧或堆,是隨機化的,因此很難去預測。

Challenge3:複雜程式的路徑約束。一個成功的數據流攻擊導致漏洞程式執行記憶體錯誤,建立了一條縫合邊,繼續執行而沒有崩潰。這要求輸入要滿足所有的路徑約束,遵從程式控制流完整性的約束,並且避免非法的記憶體存取。

研究問題

檢查程式是否可以被數據流攻擊利用,如果可以,自動生成數據流攻擊。

貢獻

  • 理論化了數據流縫合,提出了一種方法來系統化地構建數據流攻擊
  • 開發了一個數據流攻擊自動化的工具FLOWSTITCH
  • 利用通用的記憶體漏洞構建數據流攻擊是可行的,並且能夠繞過控制流防禦機制 機製。

方法

數據流攻擊的示意圖,a圖是正常執行的過程。b圖是實現了攻擊,攻擊者將pw1變數變爲了b2,然後後面的操作從b2讀取0,賦值到target。導致target變爲0。如果target是setuid位,就可以進行提權了。

在这里插入图片描述

系統框架如下:

在这里插入图片描述

輸入:後面的兩個輸入都可以利用已有的符號執行工具構造(BAP,SAGE)

  • 記憶體錯誤的程式
  • 一個觸發錯誤的輸入
  • 程式的正常輸入

構造數據流攻擊的五個步驟:

  1. 爲給定程式產生一個執行追蹤。(有benign trace和error-exhibiting trace)
  2. 識別記憶體錯誤的影響,併產生路徑約束(從程式輸入到達記憶體錯誤的路徑)
  3. 使用良好追蹤來做數據流分析和敏感數據識別
  4. 從識別的敏感數據流中選擇候選縫合配件
  5. 檢查用記憶體錯誤建立的新的邊的可行性,並驗證利用

記憶體錯誤影響分析

FLOWSTITCH分析error-exhibiting trace來求出記憶體錯誤的影響I。主要是從兩個方面來評估其影響:

  • 時間影響:什麼時間記憶體錯誤會發生
  • 空間影響:由於記憶體錯誤可以被覆蓋的記憶體範圍(這個好像別的文章也有提過)

由於程式的邏輯限制了攻擊者能夠存取的記憶體範圍。爲了識別記憶體錯誤指令的空間影響,使用動態符號執行從錯誤蹤跡中產生一個符號公式。滿足公式的輸入表示執行到這個地方的記憶體錯誤指令是在意料外的地址上。

安全敏感數據識別

有四種數據是值得縫合的:

  • 輸入數據:在追蹤生成時,執行污點分析,認爲給定的輸入是一個外部污點源。
  • 輸出數據:識別一系列程式的sink,比如send,printf。用在sink裡的參數就算輸出數據。
  • 程式金鑰:
  • 許可標誌位

將後兩者數據分爲兩類:程式特定數據和通用數據。對於程式特定數據,FLOWSTITCH接受使用者設定來找到程式特定數據。對於通用數據,用以下方法來推出:

  • 系統呼叫參數:從執行路徑中識別所有的系統呼叫參數,比如setuid,unlink
  • 設定數據:將設定檔案視爲污點源,使用污點分析來追蹤設定數據的使用
  • 隨機化數據:根據設定和檢查canary的指令來識別stack canary,如果他們不在確定的記憶體區域,則識別出隨機化的地址

識別出確定的記憶體區域是使用帶有確定地址的stitch。首先檢查程式的二進制來找出不會在執行時隨機化的記憶體區域。如果程式位置獨立的,所有的在二進制header裡的地址都是確定的。FLOWSTITCH收集所有可載入的部分,然後獲取一個確定記憶體集合D。接着去搜尋良性執行路徑中所有記憶體寫指令(寫數據到確定地址處),進而識別存在這個區域的數據。

由於敏感數據的功能性,我們預先定義攻擊的目的。比如,setuid的參數改爲0,就能夠提權了。或者將web伺服器的根目錄改爲root目錄。

stitch 候選選擇

基於以下兩個原則來產生stitch:

  • 先從一條邊的stitch開始嘗試。試完了一條邊再試多條邊的。最多隻試到四條邊。
  • 認爲在地址複用前的stitch的地址是確定的。在窮盡了確定地址和複用地址的搜尋空間後,FLOWSTITCH繼續用準確地址在benign追蹤裡搜尋stitch。

候選過濾

定義了stitchability constraint來表示以下三種約束:

  • 到達記憶體錯誤指令的路徑條件
  • 繼續目標流的路徑條件
  • 控制數據的完整性

使用符號執行來產生stitchability constraint,然後送到SMT去求解。如果找不到一個輸入滿足約束,就跳到下一條stitch邊去。如果存在的話,輸入將會用來執行,來實現數據流攻擊。由於符號執行在實現上的準確性,約束可能是不完整的。所以可能會產生一些輸入導向不同的路徑。所以最後還需要驗證一下。

實現

  • 蹤跡生成:BAP框架,Pin來動態二進制插樁記錄程式執行狀態
  • 數據流生成:使用污點資訊來獲取數據流。獲取敏感數據的數據流,使用前後向切片來定位到相關的指令。
  • 約束生成和求解:BAP+Z3 SMT求解器
    • 路徑約束
    • 影響約束
    • CFI約束

結果

有效性

對8個程式,不同的漏洞,進行了測試,都能生成數據流攻擊。

在这里插入图片描述

生成的19種數據流攻擊的情況

在这里插入图片描述

搜尋空間的減少

可以從Table3的後四列看出來,節點個數減少了很多。

效能

大部分都可以在10分鐘內完成,可以說是相當快了。

在这里插入图片描述

相關工作

數據流攻擊相關工作

已經有相當多的工作提高了CFI的可行性,使得控制流劫持變得很難。因此,數據流攻擊就是另外一個很好的選擇。數據流攻擊在這篇文章發表之前,已經出現了10年。來源於Usenix 2005的這篇論文:Non-Control-Data Attacks Are Realistic Threats.

漏洞自動化利用生成

APEG,通過識別打過修補程式和未打過修補程式的二進制來產生輸入觸發這個不同點。AEG自動化生成真實的利用,來獲取一個shell。Felmetsger提出的是針對web應用的利用生成。前人的工作主要都是基於控制流劫持的利用。FLOWSTITCH是最早的自動化生成數據流攻擊的工具。

數據流攻擊的防禦

數據流攻擊可以被數據流完整性(DFI)所防禦。現有的工作通過動態資訊追蹤或合法記憶體修改指令分析來加強DFI。終極防禦是在第一步加強記憶體安全,比如Cyclone,CCured,引入了型別安全的C語言。帶CETS的SoftBound使用邊界檢查來檢測胖指針。Cling通過型別安全記憶體複用來加強記憶體空間安全。數據流攻擊的防禦需要一個完整的記憶體安全防禦。

總結

  • 應該是第一篇數據流自動化攻擊繞過防禦機制 機製的論文。
  • 這篇論文的作者在後一年也發表了DOP。