国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于系統(tǒng)調(diào)用限制的容器安全防護(hù)方案

2022-03-04 06:47邢云龍劉彥孝張立強(qiáng)
關(guān)鍵詞:白名單二進(jìn)制調(diào)用

邢云龍,嚴(yán) 飛,劉彥孝,張立強(qiáng)

空天信息安全與可信計(jì)算教育部重點(diǎn)實(shí)驗(yàn)室,武漢大學(xué)國(guó)家網(wǎng)絡(luò)安全學(xué)院,湖北 武漢 430072

0 引言

為解決軟件部署中的環(huán)境差異問題,Linux容器技術(shù)被廣泛應(yīng)用于實(shí)現(xiàn)軟件的帶環(huán)境安裝。相較于傳統(tǒng)的虛擬機(jī)技術(shù),容器技術(shù)只虛擬了部分操作系統(tǒng)層和應(yīng)用程序?qū)樱鴽]有對(duì)計(jì)算機(jī)硬件層和操作系統(tǒng)內(nèi)核層虛擬化,因此它不僅能夠更快地啟動(dòng),而且占用的系統(tǒng)資源更少。Docker是一款優(yōu)秀的開放源碼的容器管理引擎,它提供了更好的隔離和移植功能,能夠高效地創(chuàng)建、傳送和運(yùn)行容器。根據(jù)容器部署調(diào)查報(bào)告[1],僅2017年至2018年,世界范圍內(nèi)約75%的公司已經(jīng)在Docker上進(jìn)行了多種基礎(chǔ)設(shè)施部署。

雖然容器技術(shù)在多個(gè)領(lǐng)域得到廣泛應(yīng)用,但也出現(xiàn)了許多安全問題[2],如容器逃逸和提權(quán)攻擊等。為了增強(qiáng)容器的安全性,已有幾種安全策略已經(jīng)部署到容器環(huán)境中,在保證容器正常行為的前提下,極大限制了惡意攻擊者的行為。例如,Iptables[3]管理對(duì)容器網(wǎng)絡(luò)的訪問控制;capability機(jī)制[4]切割root權(quán)限,保證容器即使被攻擊者控制,也將攻擊行為限制在某一權(quán)限內(nèi);seccomp[5]限制用戶進(jìn)程可用的系統(tǒng)調(diào)用列表,以防止攻擊者濫用不必要的系統(tǒng)調(diào)用。

然而,對(duì)于任意給定的Docker容器,默認(rèn)的安全配置仍然有一個(gè)較大的攻擊平面。惡意攻擊者對(duì)系統(tǒng)調(diào)用的濫用會(huì)對(duì)系統(tǒng)造成巨大威脅:CVE-2019-11503[6]調(diào)用chdir產(chǎn)生提權(quán)攻擊;CVE-2019-3901[7]使 用perf_event_open泄 露 隱 私 信 息;CVE-2019-13648[8]利 用sigreturn系 統(tǒng) 調(diào) 用 觸 發(fā) 內(nèi) 核 漏洞。這是由于在x86-64體系結(jié)構(gòu)中,最新的Linux內(nèi)核提供了349個(gè)系統(tǒng)調(diào)用,而seccomp默認(rèn)會(huì)對(duì)所有容器禁用44個(gè)[9]系統(tǒng)調(diào)用。但通過測(cè)試發(fā)現(xiàn),大多數(shù)容器的運(yùn)行只需要100個(gè)以上的系統(tǒng)調(diào)用,而那些從來不會(huì)被使用、也不會(huì)被禁用的系統(tǒng)調(diào)用更有可能成為攻擊的跳板。

針對(duì)上述問題,本文提出了基于系統(tǒng)調(diào)用限制的容器安全防護(hù)方案。該方案首先依賴于靜態(tài)分析,以Docker鏡像為輸入,通過解析層級(jí)鏡像結(jié)構(gòu),獲取鏡像中目標(biāo)執(zhí)行路徑和目標(biāo)二進(jìn)制;然后以二進(jìn)制為標(biāo)準(zhǔn)庫建立從庫函數(shù)到對(duì)應(yīng)系統(tǒng)調(diào)用的映射表;最后將映射表和目標(biāo)二進(jìn)制中調(diào)用的庫函數(shù)進(jìn)行對(duì)比,即可輸出目標(biāo)鏡像所需要的系統(tǒng)調(diào)用白名單。其中,針對(duì)容器鏡像解析困難問題,通過解析Docker鏡像的層級(jí)文件系統(tǒng),建立dockerfile命令和鏡像層的對(duì)應(yīng)關(guān)系,并獲取容器鏡像中的目標(biāo)執(zhí)行路徑和目標(biāo)二進(jìn)制程序;針對(duì)二進(jìn)制標(biāo)準(zhǔn)庫分析時(shí)庫函數(shù)到系統(tǒng)調(diào)用的映射困難問題,建立面向二進(jìn)制的映射表,解決了系統(tǒng)調(diào)用的識(shí)別、路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)等問題。

1 相關(guān)工作

對(duì)于容器進(jìn)程和普通Linux程序,配置適當(dāng)?shù)陌踩呗詴?huì)增強(qiáng)其運(yùn)行時(shí)的安全性。但是,由于技術(shù)的限制,無法為每一個(gè)進(jìn)程定制所需的規(guī)則,過量的配置不能起到真正的保護(hù)作用。同樣,對(duì)于內(nèi)核,如果配置了過多的安全策略會(huì)導(dǎo)致其運(yùn)行時(shí)負(fù)載過高,影響工作效率。因此本部分相關(guān)工作的討論主要針對(duì)容器安全及其安全策略去冗余、應(yīng)用程序去冗余和內(nèi)核去冗余3個(gè)部分。

1.1 容器安全及其安全策略去冗余

現(xiàn)有通過限制系統(tǒng)調(diào)用增強(qiáng)容器安全的解決方案主要依賴于動(dòng)態(tài)分析。Wan等[10]跟蹤容器內(nèi)運(yùn)行的應(yīng)用程序,并生成對(duì)應(yīng)的seccomp規(guī)則。DockerSlim[11]生成seccomp過濾器并從Docker鏡像中刪除不必要的文件。Lei等[12]將容器運(yùn)行分為兩個(gè)階段,然后使用基準(zhǔn)測(cè)試工具HammerDB[13]分別動(dòng)態(tài)跟蹤兩個(gè)階段所需的系統(tǒng)調(diào)用。Cimplifier[14]使用動(dòng)態(tài)分析將運(yùn)行多個(gè)應(yīng)用程序的容器拆分為多個(gè)單一用途的容器。Rastogi等[15]通過符號(hào)執(zhí)行提出了對(duì)Cimplifier的改進(jìn)。

盡管動(dòng)態(tài)分析可以找到大多數(shù)系統(tǒng)調(diào)用,但是其仍具有一定局限性。首先,由于動(dòng)態(tài)跟蹤的不完整性,跟蹤時(shí)不能保證識(shí)別所有必需的系統(tǒng)調(diào)用。在執(zhí)行過程中,缺少的系統(tǒng)調(diào)用就會(huì)掛起被seccomp保護(hù)的進(jìn)程。其次,動(dòng)態(tài)跟蹤進(jìn)程的不同路徑需要構(gòu)造條件嚴(yán)格地輸入,特別地,用戶進(jìn)程通常調(diào)用標(biāo)準(zhǔn)庫中的各種包裝函數(shù)來調(diào)用系統(tǒng)調(diào)用,這會(huì)極大地增加跟蹤的復(fù)雜性。

Ghavamnia等[16]在此基礎(chǔ)上提出了動(dòng)態(tài)和靜態(tài)結(jié)合的方法。動(dòng)態(tài)啟動(dòng)一個(gè)容器,然后監(jiān)控指定時(shí)間內(nèi)容器中運(yùn)行的所有二進(jìn)制程序,最后使用靜態(tài)分析方法獲取二進(jìn)制所需的系統(tǒng)調(diào)用。但是,由于不是所有容器中的二進(jìn)制程序都在容器的啟動(dòng)階段運(yùn)行,那些只在容器運(yùn)行期間調(diào)用的二進(jìn)制程序所需的系統(tǒng)調(diào)用就可能不在最后的白名單之中。例如,對(duì)于Ubuntu容器鏡像,其啟動(dòng)過程只會(huì)運(yùn)行bash和少量的常用命令,其他常用命令,如ping,就不會(huì)在啟動(dòng)階段運(yùn)行。本文基于靜態(tài)分析,通過解析層級(jí)容器鏡像,提取目標(biāo)程序,然后為標(biāo)準(zhǔn)庫構(gòu)建函數(shù)調(diào)用圖,最后對(duì)比目標(biāo)程序中調(diào)用的庫函數(shù)和映射表就可以得到完整的容器所需的系統(tǒng)調(diào)用白名單。

1.2 應(yīng)用程序去冗余

已有的應(yīng)用程序去冗余方案主要基于在單個(gè)過程中刪除不必要的代碼。Mulliner等[17]在程序加載時(shí)刪除所有未導(dǎo)入的函數(shù)。Quach等[18]改進(jìn)了編譯器,在程序編譯時(shí)識(shí)別函數(shù)邊界并移除不必要的函數(shù)。Agadakos等[19]在二進(jìn)制級(jí)執(zhí)行依賴庫的定制化,減少程序冗余。Porter等[20]僅在請(qǐng)求時(shí)加載庫函數(shù),并將程序當(dāng)前運(yùn)行所需的庫函數(shù)部分保留在進(jìn)程地址空間。Qian等[21]使用訓(xùn)練和啟發(fā)式方法來識(shí)別可以從二進(jìn)制文件中刪除的基本塊。Ghaffarinia等[22]限制了二進(jìn)制文件的控制流。Ghavamnia等[23]基于低級(jí)虛擬機(jī)(low level virtual machine,LLVM)為二進(jìn)制構(gòu)建函數(shù)調(diào)用圖,根據(jù)函數(shù)調(diào)用圖的階段分割點(diǎn),獲取各階段所需的系統(tǒng)調(diào)用列表。但是,由于兩個(gè)階段的分割點(diǎn)是手工選取的,所以該方法的實(shí)用性較低。De Marinis等[24]通過靜態(tài)分析為二進(jìn)制構(gòu)建函數(shù)調(diào)用圖,并從調(diào)用圖葉子節(jié)點(diǎn)獲取所需的系統(tǒng)調(diào)用。以上兩種方法在面向容器分析時(shí)不能解析層級(jí)鏡像結(jié)構(gòu),而且很難應(yīng)用于多語言分析的情景,并且對(duì)于一些在代碼中無法獲取的環(huán)境相關(guān)的系統(tǒng)調(diào)用,這些方案同樣不能獲取。

本文在針對(duì)二進(jìn)制程序定制所需系統(tǒng)調(diào)用時(shí),采用匹配標(biāo)準(zhǔn)庫中系統(tǒng)調(diào)用號(hào)的傳值模式,并使用回溯法確定相關(guān)寄存器的值,設(shè)計(jì)了基于鄰接矩陣的函數(shù)映射關(guān)系提取算法,解決了構(gòu)建映射表時(shí)因調(diào)用關(guān)系復(fù)雜引起的路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)問題。

1.3 內(nèi)核去冗余

現(xiàn)有針對(duì)內(nèi)核去冗余的方案主要是根據(jù)用戶要求對(duì)其進(jìn)行自定義操作。KASR[25]和FACECHANGE[26]使用動(dòng)態(tài)分析來識(shí)別內(nèi)核中未使用的部分,并使用虛擬化機(jī)制將每個(gè)應(yīng)用程序限制在其配置文件范圍內(nèi)。Kurmus等[27]提出了一種通過自動(dòng)生成內(nèi)核配置文件來針對(duì)特殊工作負(fù)載定制Linux內(nèi)核的方法。但是由于內(nèi)核去冗余在解決容器安全問題時(shí),會(huì)引入較大開銷,所以本文方案主要對(duì)前兩種去冗余安全進(jìn)行研究。

2 系統(tǒng)架構(gòu)

本文旨在為給定Docker容器自動(dòng)化生成最小且完整的系統(tǒng)調(diào)用白名單,然后通過限制不需要的系統(tǒng)調(diào)用來有效減小給定容器的攻擊面。圖1為本文系統(tǒng)框架。

圖1 系統(tǒng)架構(gòu)Fig.1 System architecture

如圖1所示,本文系統(tǒng)主要包括兩個(gè)模塊:基于層級(jí)鏡像解析的目標(biāo)程序提取和基于二進(jìn)制標(biāo)準(zhǔn)庫分析的映射關(guān)系獲取。本文方案首先通過分析鏡像的配置文件確定層間的父子邏輯關(guān)系,然后建立與dockerfile命令的一一對(duì)應(yīng)關(guān)系,通過分析dockerfile即可準(zhǔn)確定位鏡像每一層的主要功能,最后通過導(dǎo)出鏡像的文件系統(tǒng),可以獲得鏡像中的目標(biāo)二進(jìn)制程序。

獲取目標(biāo)二進(jìn)制程序后,需要分析該程序所需的系統(tǒng)調(diào)用,但是由于程序調(diào)用系統(tǒng)調(diào)用的規(guī)則復(fù)雜,且當(dāng)通過庫函數(shù)調(diào)用系統(tǒng)調(diào)用時(shí),對(duì)應(yīng)的庫函數(shù)所需要的系統(tǒng)調(diào)用也無法獲取,從而導(dǎo)致分析過程無法執(zhí)行。為此,本文提出建立基于二進(jìn)制分析的標(biāo)準(zhǔn)庫映射表,核心思想是解決為二進(jìn)制標(biāo)準(zhǔn)庫建立從庫函數(shù)到對(duì)應(yīng)系統(tǒng)調(diào)用映射表時(shí)存在的系統(tǒng)調(diào)用號(hào)識(shí)別困難、路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)等問題。

3 基于層級(jí)鏡像解析的目標(biāo)程序提取

基于層級(jí)鏡像解析的目標(biāo)程序提取主要定位鏡像中的目標(biāo)執(zhí)行路徑和目標(biāo)二進(jìn)制文件。但是,存在如下問題:

1)Docker鏡像的組織結(jié)構(gòu)復(fù)雜,使用了具有層級(jí)結(jié)構(gòu)的聯(lián)合文件系統(tǒng)(UnionFS),且每一層的命名都是該層內(nèi)容的SHA-256值,導(dǎo)致無法從每層的命名中推測(cè)該層的主要功能;

2)Docker鏡像各層間存儲(chǔ)時(shí)相互獨(dú)立,可以被不同Docker鏡像共享,所以鏡像分析時(shí)需要確定每個(gè)鏡像擁有哪些層,以及各層間的邏輯關(guān)系。

為了解決這些問題,本方案中基于層級(jí)鏡像解析的目標(biāo)程序提取主要解決兩個(gè)核心問題:層級(jí)鏡像中目標(biāo)層的定位和目標(biāo)層中目標(biāo)程序的獲取。

3.1 層級(jí)鏡像中目標(biāo)層的定位

為了定位目標(biāo)層,我們首先介紹dockerfile、Docker鏡像和Docker容器之間的區(qū)別。dockerfile是一個(gè)文本文檔,包含用戶可用于組裝Docker映像的所有命令[28]。在使用docker build命令之后,Docker逐行執(zhí)行dockerfile中的命令并在鏡像中創(chuàng)建文件系統(tǒng)。Docker鏡像中的所有層都是只讀的,而Docker容器是鏡像的運(yùn)行實(shí)例。在容器運(yùn)行時(shí),將在所有只讀層之上創(chuàng)建一個(gè)可寫層用于記錄操作期間所有的更改,并且在容器關(guān)閉后,在可寫層執(zhí)行的所有操作都會(huì)消失。為了記錄這些操作,需要重新將容器打包為鏡像,從而使得容器再次運(yùn)行時(shí)能恢復(fù)所有操作。

dockerfile命令和鏡像層的對(duì)應(yīng)關(guān)系如圖2所示。由圖2可知,當(dāng)使用docker save命令導(dǎo)出鏡像的靜態(tài)文件系統(tǒng)時(shí),每一層內(nèi)都會(huì)有一個(gè)名為json的配置文件,該文件記錄了本層ID(LayerID)和父層ID(ParentID),通過分析所有層的配置文件,即可建立鏡像所有層的鏈?zhǔn)礁缸雨P(guān)系。又因?yàn)閐ockerfile中的每條指令都構(gòu)成一個(gè)鏡像層,所以dockerfile中的指令數(shù)就是目標(biāo)鏡像的層數(shù)。通過分析dockerfile的結(jié)構(gòu),可以確定目標(biāo)二進(jìn)制在鏡像中的層號(hào)。為了分析dockerfile的結(jié)構(gòu),首先區(qū)分基礎(chǔ)鏡像(base image)和父鏡像(parent image)?;A(chǔ)鏡像提供了操作平臺(tái)和相關(guān)環(huán)境,在其dockerfile中具有FROM scratch命令?;A(chǔ)鏡像的dockerfile中ENTRYPOINT命令指示了容器開始的執(zhí)行位置,并且平臺(tái)中的功能由/bin目錄下的可執(zhí)行程序提供。對(duì)于父鏡像,它們是基于基礎(chǔ)鏡像構(gòu)建的具有特定功能的上層鏡像,例如redis容器。父鏡像安裝軟件的RUN命令位于dockerfile的目標(biāo)層,通過定位該命令即可定位到鏡像中的目標(biāo)層。通常,對(duì)于使用ENTRYPOINT命令的父鏡像,該命令中的可執(zhí)行文件將是目標(biāo)二進(jìn)制文件,這可能會(huì)節(jié)省搜索時(shí)間,提高定位性能。

圖2 dockerfile命令和鏡像層的對(duì)應(yīng)Fig.2 Correspondence between dockerfile command and image layer

3.2 目標(biāo)層中目標(biāo)程序的獲取

獲取目標(biāo)層號(hào)后,將其映射到鏡像中的對(duì)應(yīng)層即可定位目標(biāo)二進(jìn)制程序。通過比較鏡像中每層和dockerfile中的對(duì)應(yīng)命令,可以在鏡像中定位目標(biāo)層。如果該鏡像是基礎(chǔ)鏡像,則可以在/bin目錄和其子目錄中找到目標(biāo)可執(zhí)行文件,即目標(biāo)程序。對(duì)于父鏡像,目標(biāo)二進(jìn)制文件存在于目標(biāo)層的ENTRYPOINT或/bin目錄和其子目錄中。

4 基于二進(jìn)制標(biāo)準(zhǔn)庫分析的映射關(guān)系獲取

基于二進(jìn)制標(biāo)準(zhǔn)庫分析的映射關(guān)系獲取方法,需要重點(diǎn)解決從二進(jìn)制標(biāo)準(zhǔn)庫的庫函數(shù)到對(duì)應(yīng)系統(tǒng)調(diào)用映射表建立時(shí),所存在的系統(tǒng)調(diào)用號(hào)識(shí)別困難、路徑爆炸與調(diào)用節(jié)點(diǎn)回環(huán)等問題。與其他方案不同,本文不依賴于庫的源代碼,通過使用反匯編工具objdump將標(biāo)準(zhǔn)庫反匯編為匯編代碼,并且分析代碼中的調(diào)用關(guān)系。本節(jié)主要解決兩個(gè)核心問題:確定系統(tǒng)調(diào)用號(hào);解決路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)問題。

4.1 確定系統(tǒng)調(diào)用號(hào)

在匯編程序中,系統(tǒng)調(diào)用通過將系統(tǒng)調(diào)用號(hào)傳值給寄存器eax或rax,然后觸發(fā)軟中斷切換到內(nèi)核模式請(qǐng)求相關(guān)內(nèi)核服務(wù)。傳統(tǒng)的系統(tǒng)調(diào)用中斷指令是int 0x80,可是在當(dāng)前系統(tǒng)中,為了提高調(diào)用效率,該指令已被syscall和sysenter所代替。并且,通過觀察發(fā)現(xiàn),在將系統(tǒng)調(diào)用號(hào)傳給eax或rax時(shí),存在直接和間接等不同的傳值模式,包括:

模式1:直接將常量傳值給eax寄存器;

模式2:直接將常量傳值給rax寄存器;

模式3:將常量傳值給另一個(gè)寄存器,然后再把該寄存器的值復(fù)制到eax寄存器;

模式4:進(jìn)行一些數(shù)值運(yùn)算,然后將結(jié)果傳值給eax(通常使用xor eax、eax將eax值置0)。

為了確定代碼中直接調(diào)用的系統(tǒng)調(diào)用,首先,根據(jù)系統(tǒng)調(diào)用號(hào)的傳值模式,定義了4種對(duì)應(yīng)的匹配模式,如圖3所示,并根據(jù)系統(tǒng)調(diào)用指令,如syscall,將程序代碼切分為多個(gè)部分。然后,使用回溯法確定eax或rax寄存器的位置。定位到eax或rax所在行后,如果存在直接的常量傳值模式,則將保留該常量并繼續(xù)回溯另一個(gè)系統(tǒng)調(diào)用。如果eax或rax所在行存在另一個(gè)系統(tǒng)調(diào)用傳值,則將以同樣方式回溯該寄存器的值,直至獲取精準(zhǔn)的系統(tǒng)調(diào)用號(hào)。如果eax或rax所在行存在其他操作,如xor,則模擬計(jì)算結(jié)果,并將該值賦予eax或rax寄存器。

圖3 回溯法確定寄存器的eax或rax值Fig.3 Determination of eax or rax value of register by backtracking

在獲取eax或rax中存儲(chǔ)的系統(tǒng)調(diào)用號(hào)后,將其與記錄系統(tǒng)調(diào)用號(hào)和系統(tǒng)調(diào)用之間關(guān)系的系統(tǒng)文件unistd.h進(jìn)行對(duì)比,即可獲取對(duì)應(yīng)的系統(tǒng)調(diào)用。然后使用一些特殊標(biāo)記將這些系統(tǒng)調(diào)用插入到原始匯編代碼中,例如,將syscall read標(biāo)記為代碼中read的系統(tǒng)調(diào)用。

4.2 解決路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)

在objdump反匯編的匯編代碼中,每個(gè)函數(shù)名都包含在“<”和“>”之間。對(duì)于調(diào)用者函數(shù),在函數(shù)名后會(huì)跟隨“:”。因此,為了獲取函數(shù)調(diào)用關(guān)系,形成函數(shù)調(diào)用圖,首先,預(yù)處理匯編代碼并保留特殊標(biāo)記的相關(guān)行,如“<”、“>”、“:”和syscall標(biāo)記。簡(jiǎn)而言之,對(duì)原始匯編代碼進(jìn)行了簡(jiǎn)單的優(yōu)化并刪除了對(duì)分析過程無關(guān)的部分,如行號(hào)和機(jī)器碼等。然后,可以很容易獲取一級(jí)函數(shù)調(diào)用關(guān)系,如A→B和B→C。為了獲取完整的函數(shù)調(diào)用關(guān)系,如A→B、C,需要處理大量庫函數(shù)和中間函數(shù)以及這些函數(shù)間復(fù)雜的調(diào)用關(guān)系,這樣極易引起路徑爆炸和調(diào)用節(jié)點(diǎn)回環(huán)。

1)路徑爆炸。在處理函數(shù)調(diào)用圖的節(jié)點(diǎn)連接時(shí),傳統(tǒng)的圖形連接算法需要打開、檢查和匹配要分析的文件。即使在處理單個(gè)文件時(shí),也必須考慮連接節(jié)點(diǎn)的所有調(diào)用函數(shù),大量的函數(shù)和復(fù)雜的調(diào)用關(guān)系在構(gòu)造函數(shù)調(diào)用圖時(shí)就會(huì)造成路徑爆炸,占用全部處理器和內(nèi)存資源。

2)調(diào)用節(jié)點(diǎn)回環(huán)。在節(jié)點(diǎn)遍歷時(shí),如果函數(shù)出現(xiàn)調(diào)回,則函數(shù)調(diào)用圖中就會(huì)出現(xiàn)閉環(huán),當(dāng)進(jìn)行節(jié)點(diǎn)遍歷時(shí),很容易陷入無限循環(huán),空耗計(jì)算機(jī)資源。

?

為了解決這些問題,本文設(shè)計(jì)了基于鄰接矩陣的函數(shù)映射關(guān)系提取算法,如算法1所示。該算法為每個(gè)函數(shù)和系統(tǒng)調(diào)用分配一個(gè)唯一且連續(xù)的值(總計(jì)N),并使用鄰接矩陣表示調(diào)用關(guān)系,初始化為false,如第2和3行所示。第6行到第8行為第一次掃描,確定一級(jí)函數(shù)調(diào)用關(guān)系,如果兩個(gè)函數(shù)之間存在調(diào)用關(guān)系,或者該函數(shù)與系統(tǒng)調(diào)用之間存在調(diào)用關(guān)系,則鄰接矩陣中的值將設(shè)置為true。第二次掃描是最重要的部分。如果在函數(shù)i和j之間存在調(diào)用關(guān)系,則函數(shù)j調(diào)用的所有函數(shù)都有可能被函數(shù)i調(diào)用。因此,執(zhí)行OR操作將函數(shù)j中的所有調(diào)用關(guān)系分配給函數(shù)i。為了完整起見,重復(fù)此過程,直至調(diào)用關(guān)系不再增加(這里我們選擇重復(fù)100次,即N=100),如第10行到第17行所示。最后的掃描將輸出調(diào)用關(guān)系結(jié)果。如果函數(shù)i與函數(shù)j具有調(diào)用關(guān)系,則輸出兩個(gè)函數(shù)名稱。該算法針對(duì)擁有上萬個(gè)庫函數(shù)和中間函數(shù)的libc庫,可以在幾分鐘內(nèi)生成完整的函數(shù)映射表。

至此,我們已經(jīng)獲得從庫函數(shù)到對(duì)應(yīng)系統(tǒng)調(diào)用的映射表,最后將映射表和目標(biāo)二進(jìn)制程序中調(diào)用的庫函數(shù)進(jìn)行對(duì)比,即可輸出目標(biāo)鏡像所需的系統(tǒng)調(diào)用白名單。

5 實(shí)驗(yàn)結(jié)果與分析

5.1 測(cè)試環(huán)境和方案

實(shí)驗(yàn)平臺(tái)為intel i5-8265U 1.6 GHz 4核處理器和8 GB RAM,其中操作系統(tǒng)為內(nèi)核版本5.4.0的Ubuntu 20.04,GNU C庫(glibc)版本為2.29。

為了驗(yàn)證本文方案的有效性,首先選取50個(gè)下載量最高的官方Docker鏡像,根據(jù)功能將它們分為5個(gè)類別,鏡像名和其分類如表1所示。然后,通過對(duì)測(cè)試容器進(jìn)行動(dòng)態(tài)跟蹤,并與本文結(jié)果進(jìn)行對(duì)比,分析動(dòng)態(tài)跟蹤方案和本文方案的差異。在執(zhí)行動(dòng)態(tài)跟蹤時(shí),我們將盡可能遍歷容器中的所有功能。最后,收集近6年和系統(tǒng)調(diào)用相關(guān)的70個(gè)CVE(common vulnerabilities and exposure,通用漏洞披露)數(shù)據(jù)庫[29]中的漏洞,通過設(shè)置白名單,測(cè)試相關(guān)CVE防御率。

表1 測(cè)試數(shù)據(jù)集分類和鏡像名Table 1 Test dataset classification and image name

5.2 結(jié)果分析與討論

圖4~8中,動(dòng)態(tài)跟蹤表示對(duì)所有測(cè)試容器進(jìn)行動(dòng)態(tài)執(zhí)行,并使用ptrace和日志監(jiān)控獲取其生命周期所需的系統(tǒng)調(diào)用列表;本文方案表示在靜態(tài)分析下獲取二進(jìn)制所需的系統(tǒng)調(diào)用列表。通過將動(dòng)態(tài)跟蹤結(jié)果與本文方案進(jìn)行對(duì)比,可以發(fā)現(xiàn)為每個(gè)容器定制的系統(tǒng)調(diào)用白名單可以使該容器正常執(zhí)行所有功能,且動(dòng)態(tài)跟蹤獲取的系統(tǒng)調(diào)用列表是本文方案獲取白名單的真子集。通過統(tǒng)計(jì)測(cè)試集中每個(gè)容器白名單中系統(tǒng)調(diào)用的數(shù)量發(fā)現(xiàn),采用本文方案時(shí),測(cè)試容器所需的平均系統(tǒng)調(diào)用數(shù)為127個(gè)(總數(shù)為333個(gè)),即對(duì)于每個(gè)測(cè)試容器,采用本文方案平均可以攔截206個(gè)系統(tǒng)調(diào)用。

對(duì)于不同類別的容器,采用動(dòng)態(tài)跟蹤方案和本文方案時(shí)所需的系統(tǒng)調(diào)用數(shù)量也不相同(如圖4~8所示)。圖4展示了數(shù)據(jù)庫容器所需的系統(tǒng)調(diào)用,采用本文方案獲取的平均系統(tǒng)調(diào)用為121個(gè),調(diào)用數(shù)量最少的容器僅使用93個(gè)系統(tǒng)調(diào)用,最多不超過160個(gè)系統(tǒng)調(diào)用;采用動(dòng)態(tài)跟蹤方案時(shí),測(cè)試集中容器所需系統(tǒng)調(diào)用最多為136個(gè),最少僅需70個(gè)系統(tǒng)調(diào)用。對(duì)于圖5中所示操作系統(tǒng)容器,這些容器都共享著相似的基礎(chǔ)鏡像,且這些基礎(chǔ)鏡像執(zhí)行通用命令并幾乎擁有所有的基礎(chǔ)庫,如果排除此類別,則采用本文方案時(shí)測(cè)試集的系統(tǒng)調(diào)用可以減少70%。圖6中顯示了編程語言容器所需的系統(tǒng)調(diào)用,在本方案下,其執(zhí)行過程最多需要156個(gè)系統(tǒng)調(diào)用。對(duì)于圖7中基礎(chǔ)架構(gòu)容器,采用本文方案時(shí),其所需的系統(tǒng)調(diào)用數(shù)量相對(duì)比較穩(wěn)定,均值和中位數(shù)比較接近。對(duì)于圖8中所示的開發(fā)運(yùn)維容器,采用本文方案時(shí),其所需的系統(tǒng)調(diào)用數(shù)量少于150個(gè)。

圖4 數(shù)據(jù)庫容器所需的系統(tǒng)調(diào)用Fig.4 System calls required by the database container

圖5 操作系統(tǒng)容器所需的系統(tǒng)調(diào)用Fig.5 System calls required by the operating system container

圖6 編程語言容器所需的系統(tǒng)調(diào)用Fig.6 System calls required by the programming language containers

圖7 基礎(chǔ)架構(gòu)容器所需的系統(tǒng)調(diào)用Fig.7 System calls required by the infrastructure container

圖8 開發(fā)運(yùn)維容器所需的系統(tǒng)調(diào)用Fig.8 System calls required by the develop and maintain containers

總而言之,通過為Docker容器設(shè)置所需的白名單,可以極大地減小其攻擊平面,有效防御和系統(tǒng)調(diào)用相關(guān)的軟件漏洞。另外,由于Docker容器在運(yùn)行時(shí)默認(rèn)加載了seccomp過濾規(guī)則,所以為容器定制白名單不會(huì)產(chǎn)生額外的性能開銷。

為了進(jìn)一步確定動(dòng)態(tài)跟蹤結(jié)果和本文方案結(jié)果差距的原因,本文手動(dòng)調(diào)試了一些鏡像,包括編譯和運(yùn)行模式、條件分支和未調(diào)用的函數(shù),并分析了引起差異的原因。

1)編譯和運(yùn)行模式。對(duì)于某些應(yīng)用程序,其編譯和運(yùn)行存在不同的模式,其編譯選項(xiàng)只在運(yùn)行時(shí)確定,并且為了保證程序的正常運(yùn)行,不同編譯模式所需的系統(tǒng)調(diào)用都存在于代碼中。但是,在進(jìn)行動(dòng)態(tài)跟蹤時(shí),只能獲取一個(gè)或其中一部分分支所需要的系統(tǒng)調(diào)用,這就會(huì)錯(cuò)過對(duì)其他分支的分析,從而造成系統(tǒng)調(diào)用的遺漏。例如,redis在動(dòng)態(tài)跟蹤時(shí),可以在使能tls模式下進(jìn)行編譯和運(yùn)行,以增強(qiáng)傳輸安全性。

2)條件分支。在應(yīng)用程序中,各種分支實(shí)現(xiàn)不同的功能,所有這些分支構(gòu)成函數(shù)調(diào)用圖。但是在動(dòng)態(tài)跟蹤中,即使借助fuzzing技術(shù)(通過更改輸入并多次執(zhí)行應(yīng)用程序)也很難覆蓋所有分支。那些未被覆蓋的分支所調(diào)用的系統(tǒng)調(diào)用就不會(huì)出現(xiàn)在動(dòng)態(tài)跟蹤的結(jié)果里,造成動(dòng)態(tài)跟蹤和本文方案結(jié)果的差異。

3)未調(diào)用的函數(shù)。在程序的匯編代碼中,某些函數(shù)與其他函數(shù)沒有直接調(diào)用關(guān)系,這些函數(shù)的執(zhí)行是通過運(yùn)行時(shí)參數(shù)跳轉(zhuǎn)到該函數(shù)的入口地址實(shí)現(xiàn)的。如果在動(dòng)態(tài)執(zhí)行期間沒有其他函數(shù)調(diào)用此函數(shù),則將無法獲得該函數(shù)調(diào)用的系統(tǒng)調(diào)用。但是,在采用本文方案分析靜態(tài)庫函數(shù)時(shí),將包括該函數(shù)調(diào)用的系統(tǒng)調(diào)用,這會(huì)導(dǎo)致動(dòng)態(tài)跟蹤結(jié)果與本文方案所得最終系統(tǒng)調(diào)用白名單之間的差異。

為了證明定制的系統(tǒng)調(diào)用將減少容器的攻擊面,本文收集了最近6年和系統(tǒng)調(diào)用相關(guān)的70個(gè)CVE數(shù)據(jù)庫中的漏洞,然后測(cè)試不同數(shù)據(jù)集對(duì)于設(shè)置系統(tǒng)調(diào)用白名單后的軟件漏洞防御率,結(jié)果如圖9所示。由圖9可知,不同類別的容器貢獻(xiàn)了不同的漏洞防御率。其中,操作系統(tǒng)容器的漏洞防御率最低,最少可以防御58%的軟件漏洞,對(duì)于半數(shù)以上的測(cè)試容器,都可以防御超過64%的軟件漏洞。編程語言類容器的漏洞防御最高,其中一半可以防御74%的漏洞。其他3個(gè)類別容器的漏洞防御率在60%至88%之間。因此,如果根據(jù)其系統(tǒng)調(diào)用白名單并利用seccomp來限制對(duì)容器的系統(tǒng)調(diào)用,則至少58%的漏洞無法被所有測(cè)試容器利用,而超過70%的漏洞不能被一半測(cè)試容器所利用。因此,通過提取和限制對(duì)應(yīng)用程序的必要系統(tǒng)調(diào)用,可以防止應(yīng)用程序可能的漏洞利用。

圖9 不同測(cè)試集的軟件漏洞防御率Fig.9 Software vulnerability defense rate of the different test set

6 結(jié)語

seccomp可用來限制進(jìn)程可用的系統(tǒng)調(diào)用,但是,對(duì)于給定容器進(jìn)程仍然缺少自動(dòng)化定制所需系統(tǒng)調(diào)用白名單的技術(shù)。本文設(shè)計(jì)了一種基于系統(tǒng)調(diào)用限制的容器安全自動(dòng)化防護(hù)方案,為給定容器自動(dòng)化生成所需系統(tǒng)調(diào)用列表。首先,解析docker?file并構(gòu)建與鏡像層的對(duì)應(yīng)關(guān)系,在目標(biāo)鏡像層中定位目標(biāo)二進(jìn)制文件。然后,使用靜態(tài)分析為依賴庫建立從庫函數(shù)到對(duì)應(yīng)系統(tǒng)調(diào)用的映射表,并將其與二進(jìn)制文件中的被調(diào)用函數(shù)進(jìn)行比較,以獲取被調(diào)用的系統(tǒng)調(diào)用。為驗(yàn)證本文方案的有效性,選擇了下載量前50的Docker鏡像作為測(cè)試集,分別測(cè)試其相較于默認(rèn)系統(tǒng)調(diào)用列表的系統(tǒng)調(diào)用減少量和對(duì)于系統(tǒng)調(diào)用相關(guān)軟件漏洞的防御率。實(shí)驗(yàn)結(jié)果表明,采用本文方案時(shí),這些鏡像所調(diào)用的平均系統(tǒng)調(diào)用數(shù)為127個(gè)。在限制可用的系統(tǒng)調(diào)用之后,可以阻止大多數(shù)和系統(tǒng)調(diào)用相關(guān)的軟件漏洞。在今后的研究中,我們會(huì)進(jìn)一步細(xì)粒度地分析容器不同階段所需的系統(tǒng)調(diào)用,根據(jù)不同階段定制白名單。

猜你喜歡
白名單二進(jìn)制調(diào)用
UAC提示太煩 教你做個(gè)白名單
有用的二進(jìn)制
用Scratch把十進(jìn)制轉(zhuǎn)為二進(jìn)制
有趣的進(jìn)度
2019年“移動(dòng)互聯(lián)網(wǎng)應(yīng)用自律白名單”出爐
基于Android Broadcast的短信安全監(jiān)聽系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)
移動(dòng)互聯(lián)網(wǎng)白名單認(rèn)證向中小企業(yè)開放
船企“白名單”, 銀行怎么看
利用RFC技術(shù)實(shí)現(xiàn)SAP系統(tǒng)接口通信
C++語言中函數(shù)參數(shù)傳遞方式剖析
富平县| 时尚| 朔州市| 城口县| 中西区| 定边县| 蕉岭县| 肇东市| 高清| 崇阳县| 安平县| 谢通门县| 德钦县| 抚州市| 峨边| 平南县| 鸡泽县| 文登市| 府谷县| 广饶县| 龙州县| 吴堡县| 长阳| 阳高县| 客服| 黄龙县| 肥乡县| 岳普湖县| 山阴县| 郎溪县| 玉山县| 禹城市| 赞皇县| 文山县| 建平县| 蒙自县| 彭泽县| 嵩明县| 塘沽区| 定襄县| 鱼台县|