縫合線是基於LLVM IR並建立在Checker博士(非常感謝其創建者!)的靜態點對點和高級污點分析工具(對於C),兩個亮點是:
我們將其命名為縫合線,希望它能在手術上精確,同時能夠將多個SYSCALL/輸入功能縫合在一起以構建高階數據流。有關更多詳細信息,請參閱我們的論文:在ACM CCS'21中的OS內核中靜態發現高階污染樣式漏洞。
首先克隆回購:
~$ git clone https://github.com/seclab-ucr/SUTURE.git suture
然後設置縫合線的LLVM環境:
~$ cd suture
~/suture$ python setup_suture.py -o ../suture_deps
選項(用於setup_suture.py ):
-b指定要為縫合線設置的LLVM的分支名稱,在此LLVM Mirror Repo中默認為“ Release_90”(即LLVM 9.0)。-o指定該文件夾託管縫合線(例如LLVM)所需的所有內容,請使用您喜歡的任何文件夾。根據您的硬件,LLVM設置可能需要一段時間。完成後,將在縫合根文件夾下生成一個名為env.sh的SRCIPT文件,它包含命令來設置縫合線使用的環境變量。
重要的是:請確保在構建/使用縫合線之前每次都要激活此env.sh (您還可以將其包含的命令添加到.bashrc中,以在外殼登錄時自動激活)!
~/suture$ source env.sh
接下來,我們將建造縫合線:
~/suture$ cd llvm_analysis
~/suture/llvm_analysis$ ./build.sh
成功的構建後,縫合線就可以使用了。
縫合線可用於發現現成的高階污點漏洞,在本節中,我們將瀏覽此過程的示例(例如,我們的論文第2.1節所示的激勵示例)。
要發現漏洞縫合線需要兩種輸入:(1)編譯為LLVM比特代碼(例如, .bc文件)的程序模塊,以及(2)模塊的配置文件,顯示其輸入功能和用戶控制的參數。
讓我們首先準備LLVM比特碼用於我們的激勵示例:
~/suture$ cd benchmark
~/suture/benchmark$ ./gen.sh motivating_example
注意:為方便起見,我們提供了gen.sh ,以-O1優化級別將.c彙編為.bc和.bc和.ll (人類可讀LLVM比特碼)。
現在,我們應該在同一基準文件夾下將Motivating_example.bc放在縫合線的同一基准文件夾下。
然後,它涉及配置文件,我們已經為激勵示例準備了一個:
~/suture/benchmark$ cat conf_motivating_example
entry0 MY_IOCTL 1
entry1 NULL_ARG
entry2 NULL_ARG
說明:配置文件中的每一行描述了一個輸入函數的信息(例如,帶有呼叫者的頂級函數,通常用作外部接口),在程序模塊中,它包含多達3個空格分隔的令牌:
entry_x MY_IOCTL 0_2中指定它。因此,如上所述, conc_motivating_example指定suptivating_example.c : entry00 (參數1是用戶控制), entry1和entry2 (沒有用戶控制的參數)中有三個輸入函數。這符合激勵示例的代碼。
一旦準備好的比特代碼和輸入配置文件,我們就可以運行縫合線以發現污點漏洞:
~/suture$ ./run_nohup.sh benchmark/motivating_example.bc benchmark/conf_motivating_example
說明: run_nohup.sh是一個簡單的腳本,調用了縫合的llvm分析通過:
~/suture$ ./run_nohup.sh [path/to/program.bc] [path/to/entry_func_config]
一旦開始,根據目標程序的實際硬件和復雜性,縫合線完成分析和脆弱性發現所需的時間差異很大。但是,像我們激勵示例這樣的簡單程序通常會立即完成。
確定分析是否完成:在執行過程中,縫合線在輸入配置文件的相同目錄下繼續登錄文件,假設配置文件路徑為/路徑/to/conf_program ,日誌文件將為/path/to/to/conf_program.log 。我們可以通過監視日誌來確定分析是否完成:
~/suture$ grep "Bug Detection Phase finished" benchmark/conf_motivating_example.log
上述日誌文件也是縫合線的輸出,縫合線將其發現的潛在漏洞嵌入日誌文件中,分析完成後可以將其提取並組織到最終的警告報告中:
~/suture$ ./ext_warns.sh benchmark/conf_motivating_example.log
說明: ext_warns.sh將提取嵌入給定日誌文件中的所有警告(在JSON中),重新組織並精心打印到最終的警告報告中。警告報告將在日誌文件的相同路徑下放入文件夾中,假設日誌文件為/path/path/to/conf_program.log ,警告報告文件夾將為/path/to/to/to/warns-conf_program-yyyy-mm-dd 。
~/suture$ ls benchmark/warns-conf_motivating_example-2021-11-10/
all int_overflow taint_data_use taint_loopbound taint_ptr_def
在文件夾中有5個警告報告,所有報告都包含根據其數據流關係分組在一起的所有類型的警告,而其他報告僅包含特定類型的警告(例如,整數溢出,污染的指針解答等),有關如何在論文中找到我們如何分組警告的更多詳細信息(第4節)。我們通常只使用統一報告。
~/suture$ cat -n benchmark/warns-conf_motivating_example-2021-11-10/all
1 =========================GROUP 0 (2 - 2)=========================
2 #####Warned Insts#####
3 (u'motivating_example.c', 30, [u'IntegerOverflowDetector'])
4 ######################
5
6 ++++++++++++++++WARN 0 (2 - 2)++++++++++++++++
7 IntegerOverflowDetector says: motivating_example.c@30 (bar : %add = add i8 %0, -16, !dbg !31)
8 ********Trace 0(2)********
9 #####CTX##### entry0
10 entry0 (motivating_example.c@18)
11 #####INSTS#####
12 >>>>>>>>>>>>>>>>>>tag: 0x55b206570420 tf: 0x55b20695b1b0 (2)>>>>>>>>>>>>>>>>>>
13 motivating_example.c@18 ( %cond = icmp eq i32 %cmd, 0, !dbg !31)
14 motivating_example.c@21 ( store i8 %user_input, i8* getelementptr inbounds (%struct.data, %struct.data* @d, i64 0, i32 1, i64 0), align 4, !dbg !32, !tbaa !34)
15 #####CTX##### entry1 -> bar
16 entry1 (motivating_example.c@35)
17 ----> (motivating_example.c@35 : %call = tail call i32 @bar(i8* bitcast (%struct.data* @d to i8*)), !dbg !27)
18 bar (motivating_example.c@30)
19 #####INSTS#####
20 >>>>>>>>>>>>>>>>>>tag: 0x55b2065e7050 tf: 0x55b2068174f0 (1)>>>>>>>>>>>>>>>>>>
21 motivating_example.c@30 ( %0 = load i8, i8* %add.ptr, align 1, !dbg !31, !tbaa !32)
22 motivating_example.c@30 ( %add = add i8 %0, -16, !dbg !31)
23
說明:在高級別,警告報告包含一些警告組,每個組包含多個警告,每個警告包含幾個污點痕跡,這些痕跡源自用戶輸入和接收器到相同的敏感程序語句。換句話說,針對特定類型和特定類型(例如,整數溢出)提出了一個警告,而一組從數據流角度包含多個密切相關的警告(請參閱本文中的第4節),因此,一組可能具有多個警告程序語句,並包含不同的警告類型。
以上述警告報告為例:
===GROUP No. (min_order - max_order)=== ,其中min_order是最小訂單(例如,簡單地說,訂單,訂單是污點傳播中所需的輸入函數的時代,請參見第3.2節中的第3.2節,以max_order本組的更正式定義。WARN No.是其組的本地。***Trace No. (order)*** ,污點痕跡總是具有可以計算的唯一順序(例如,不是范圍)。警告報告指出了有效的整數溢出漏洞在激勵示例中,同時避免了可能生成不太精確的靜態分析工具的潛在錯誤警報,可以在我們的論文第2.1節中找到詳細信息。
此存儲庫還包含一些您可能會發現有用的其他工具/腳本。
~/suture$ python llvm_analysis/AnalysisHelpers/EntryPointIdentifier/entry_point_identifier.py /path/to/prog_module.bc
~/suture$ cat /path/to/prog_module.bc.all_entries
說明:此腳本可以在Linux設備驅動程序模塊(例如ioctl() , read() , write()等)中識別一些常見的輸入功能,這些功能有助於構建輸入配置文件作為縫合的輸入。該實用程序主要由原始Dr. Checker基於某些內核域知識實現(例如,用於定義驅動程序的特定數據結構(例如用於定義驅動程序入口點的File_operations ),然後我們進行了一些改進(例如,使啟發式術更強大)。
~/suture$ python flt_warns.py /path/to/warn_report [Regex] > /path/to/filtered_warn_report
說明:根據我們的經驗,警告報告中的許多虛假警報通常共享相同的有問題的子污染跟踪(請參閱第6.3節中的第6.3節)。只要警告審稿人檢查一個錯誤警報並識別出FP引起的子跟踪,她自然可以嘗試自動排除所有包含相同子跟踪的所有其他類似的錯誤警報,從而降低了審閱者感知的錯誤警報率。為此,我們提供了以原始警告報告和Python正則表達式為輸入的簡單flt_warns.py ,然後將其與報告中的每個污點相匹配,一旦匹配,污點痕跡將被視為誤報。該腳本將生成一個新的過濾警告報告,不包括所有匹配的污點痕跡。
您可能有興趣將縫合線用作通用靜態分析(例如,在某個程序位置獲取變量的點數/污點),這肯定是可行的,但是與漏洞發現不同,您需要弄髒並深入研究縫線守則以熟悉縫線的主要數據結構IT和某些重要功能。我希望以下技巧可以幫助:
LLVM很快發展,無法保證向後兼容。因此,在嘗試使用較新的LLVM版本(例如,> 9.0)構建縫合線時,您很可能會遇到一些彙編錯誤。但是幸運的是,這種彙編錯誤通常很容易解決(例如,通常我們只需要用較新的情況替換過時的LLVM API)即可。因此,基本上,要將縫合物調整到更新的LLVM版本中,首先我們需要在0x0中設置一個較新的LLVM(例如,需要將setup_suture.py修改為從活動源中克隆llvm repo,並指定新的分支名稱),然後嘗試構建suture,以構建suture,以彌補索引的彙編編輯錯誤。