999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Docker組件間標準輸入輸出復制的DoS攻擊分析

2020-12-18 00:05:06周天昱申文博楊男子李金庫秦承剛喻望
網(wǎng)絡與信息安全學報 2020年6期
關鍵詞:分析

周天昱,申文博,楊男子,李金庫,秦承剛,喻望

Docker組件間標準輸入輸出復制的DoS攻擊分析

周天昱1,2,申文博2,楊男子3,李金庫3,秦承剛4,喻望4

(1. 浙江大學NGICS大平臺,浙江 杭州 310027;2. 浙江大學網(wǎng)絡空間安全學院,浙江 杭州 310027;3. 西安電子科技大學網(wǎng)絡與信息安全學院,陜西 西安 710071;4. 螞蟻科技集團股份有限公司,浙江 杭州 310000)

近年來,Docker技術因其部署靈活、可擴展性強,獲得了大規(guī)模應用。Docker采用模塊化設計,在降低開發(fā)和維護的復雜性的同時引入了針對組件間通信的拒絕服務(DoS)攻擊。在Docker容器內頻繁進行stdout輸出會引起Docker組件消耗大量CPU,造成DoS攻擊。經過分析,可發(fā)現(xiàn)容器實例中的stdout輸出會觸發(fā)Docker各個組件的goroutine,進行頻繁輸出復制。為系統(tǒng)化地找出可被DoS攻擊的goroutine創(chuàng)建的路徑,提出使用靜態(tài)分析的方法來分析Docker各組件,設計并實現(xiàn)了Docker組件靜態(tài)分析框架,最后在Docker上進行了測試,成功分析得到了34條此類路徑,其中22條路徑經驗證,可成功被動態(tài)觸發(fā)。

容器;Docker組件;DoS攻擊;靜態(tài)分析

1 引言

近年來,以Docker為代表的容器技術因其部署靈活,可擴展性強而獲得了廣泛的應用。在具體實現(xiàn)上,Docker采用模塊化設計,根據(jù)功能分為不同的模塊(又稱組件),包含Docker命令行、Docker守護進程、容器守護進程以及runc等組件。這些組件實現(xiàn)了功能上的緊密聚合,各個組件間采用文件或者socket通信,實現(xiàn)了容器的快速創(chuàng)建和靈活管理。Docker的模塊化設計使各個模塊可以獨立開發(fā)和設計,降低了開發(fā)和維護的復雜性。此外,模塊化設計提升了Docker的可擴展性,如gVisor使用runsc(sand-boxed container)替換runc,提升容器安全性的同時,與上層Docker的接口實現(xiàn)了無縫結合。

但是,Docker的模塊化設計引入了利用組件間通信進行拒絕服務(DoS)攻擊的可攻擊面。本文發(fā)現(xiàn)使用printf在容器實例內持續(xù)輸出數(shù)據(jù)到stdout,可以引發(fā)Docker組件的高CPU消耗,造成對宿主機CPU資源的DoS攻擊。其原因是Docker各個組件間通過自動觸發(fā)的goroutine不斷對stdio進行復制,消耗大量CPU,導致DoS攻擊。然而此類DoS攻擊引起的CPU消耗屬于不同的Docker組件進程,而這些組件進程,被多個容器實例所共享,不屬于單個容器實例,因此無法利用cgroups進行限制。

為了找出所有可被DoS攻擊的路徑,本文提出使用靜態(tài)分析來系統(tǒng)化地找出所有具有stdio復制的goroutine,用LLVM編譯器分析Docker各組件,以負責容器實例的stdio復制的函數(shù)為特征,找到各組件內所有能創(chuàng)建goroutine并調用特征函數(shù)的路徑,然后跨組件將這些路徑連接起來,最終找到所有能觸發(fā)這些路徑的Docker命令(用戶可通過在終端輸入Docker命令和docker-cli交互并觸發(fā)這些路徑)。

要實現(xiàn)Docker組件靜態(tài)分析框架需要解決兩個技術挑戰(zhàn)。

第一,在分析Docker組件LLVM IR中的特征函數(shù)調用路徑時,由于組件使用Go語言編寫并大量使用了接口(interface),而在IR中一般以間接調用的方式來實現(xiàn)接口成員函數(shù)的調用,因此無法通過分析調用語句獲得接口成員函數(shù)的目標函數(shù),從而導致大量路徑分析在接口成員函數(shù)處斷裂,嚴重影響分析效果。為了解決該問題,本文采用基于數(shù)據(jù)流分析和函數(shù)類型匹配的方法,找到了接口成員函數(shù)的具體實現(xiàn),并建立了接口成員函數(shù)調用表輔助路徑分析。

第二,LLVM編譯器只能分析單個組件內的函數(shù)調用路徑,不同組件之間的路徑無法通過組件LLVM IR的分析得到,但用戶只能通過Docker命令和docker-cli以及后續(xù)的各個組件進行交互,因此最終路徑應為從Docker命令開始到組件內創(chuàng)建goroutine結束的跨組件路徑,然而LLVM只能分析單個組件內的調用路徑,不同組件之間的路徑無法通過組件IR分析得到。為了解決該問題,本文提出了跨組件路徑連接技術,通過分析Docker組件間通信的協(xié)議(如HTTP、gRPC和ttrpc)和相關函數(shù),利用特征字段和函數(shù)的匹配成功連接了不同組件的路徑。

本文的貢獻如下。

1) 本文針對Docker組件間stdio復制設計了一種新的DoS攻擊方法,并對該攻擊進行了分析,分析了該攻擊成功的原因,發(fā)現(xiàn)負責stdio復制的goroutine會被該攻擊不斷觸發(fā)從而消耗大量CPU。

2) 本文提出并實現(xiàn)了Docker組件靜態(tài)分析框架,系統(tǒng)化地找出所有可能被DoS攻擊的goroutine創(chuàng)建路徑。該分析框架包括接口成員函數(shù)解析,使用Pass分析各組件內調用路徑和跨組件連接路徑等新技術。

3) 本文在Docker上測試了靜態(tài)分析框架,成功找出了各組件內創(chuàng)建goroutine的路徑,并通過路徑連接分析出可被Docker命令觸發(fā)的路徑總計34條,其中22條通過動態(tài)驗證確定可被觸發(fā)。

2 相關工作

Dockers使用cgroups(control groups)進行硬件資源的限制[1]。cgroups是Linux內核提供的用于監(jiān)控和限制進程資源的工具[2]。cgroups使用控制器(controller)來控制具體的計算資源,包括用于限制CPU使用量的CPU控制器,限制內存使用的memory控制器,限制塊設備訪問速率的blkio控制器等。用戶通過訪問cgroups提供的虛擬文件系統(tǒng)cgroupfs,以文件操作的方式來訪問和創(chuàng)建cgroup。每個cgroup都有對應的資源控制器設置,將進程添加進具體的cgroup即可限制該進程以及它的后續(xù)進程的資源訪問。

然而,Docker雖然可以限制容器實例對計算資源的訪問,惡意攻擊者仍然可以在容器實例內部對宿主操作系統(tǒng)上的計算資源進行DoS攻擊。Gao等[3]在2019年提出可以在容器實例內部觸發(fā)宿主操作系統(tǒng)中進程或線程對CPU、I/O的消耗,從而達到DoS的攻擊效果。這些被觸發(fā)的進程或線程并非由容器實例直接創(chuàng)建,不受容器實例所在cgroup的限制,且它們所在的cgroup通常不設置資源使用上限,因此可以消耗大量計算資源。本文將這種間接對計算資源進行DoS攻擊的方法分為4類:①觸發(fā)內核線程的工作流,使其消耗大量資源;②使內核線程創(chuàng)建子進程,該子進程與內核線程同屬一個cgroup,由子線程消耗大量資源;③觸發(fā)當前操作系統(tǒng)中的服務進程消耗資源;④利用中斷上下文來消耗資源。文獻[3]對每一種類型的攻擊都列舉了攻擊實例,但并未闡述是如何找到這些實例的,同時缺乏系統(tǒng)性查找全部DoS攻擊的方案。

Docker的安全問題一直是學術界和工業(yè)界關注的熱點。Bui[4]分析了Docker容器的隔離性,以及對Linux安全特性的利用。Gupta[5]比較了Docker依賴的Linux Container技術和虛擬機技術在安全性上的差別。Bacis等[6]對Dockerfile進行擴展,使用戶在能夠生成鏡像時指定SELinux[7]規(guī)則來加強容器安全性。Combe等[8]總結了不正確的Docker配置可能導致的安全漏洞。Chelladhurai等[9]探討了Docker中DoS的攻擊和防護措施。Shu等[10]探究了Docker Hub存在的安全性漏洞。Yasrab[11]總結了目前Docker容器存在的安全風險,并提出安全性更強的Docker容器部署方案。Jian等[12]總結了Docker容器逃逸攻擊的方法和特點,并提出了一種基于namespaces[13]狀態(tài)檢查的防御方法。王鵑等[14]利用可信計算的相關技術設計了Docker安全防護模塊,保護容器和鏡像不被篡改并監(jiān)控容器內部進程。Lin等[15]篩選了223個能夠在Linux操作系統(tǒng)上進行攻擊的有效攻擊方法,并從中挑選出88個典型的攻擊樣例在Docker容器當中進行測驗,最終發(fā)現(xiàn)有50個攻擊方法可以進行有效的攻擊,包括信息竊取、遠程控制、DoS和提權攻擊。

現(xiàn)有工作基本集中在Docker容器本身的安全性研究上,并未對Docker各組件通信過程中存在的漏洞進行分析和防護。

3 Docker組件介紹

Docker運行容器實例需要依賴多個組件的協(xié)同工作,各個組件通過HTTP、gRPC和ttrpc技術進行通信,發(fā)送請求與回復,如圖1所示。

圖1 Docker各組件關系

Figure 1 Relationships of Docker components

1) docker-cli是Docker為用戶提供的可以和dockerd進行交互的工具。用戶可以在終端輸入Docker命令,每次執(zhí)行命令都會創(chuàng)建一個docker-cli與之對應,docker-cli會根據(jù)用戶輸入的命令內容,將參數(shù)打包成REST格式的HTTP請求,發(fā)送到dockerd。

2) dockerd是Docker的管理進程,負責接收所有符合Docker Engine API的請求(如docker-cli發(fā)送的HTTP請求),并將容器相關的操作打包為gRPC請求發(fā)送給containerd。宿主操作系統(tǒng)中同一時間只能運行一個dockerd進程,它在初始化Docker服務的時候被創(chuàng)建,并一直運行在后臺。dockerd進程與docker-cli進程是一對多的關系,同一個dockerd進程同時為所有的docker-cli進程提供服務。

3) containerd負責容器實例的創(chuàng)建、監(jiān)控和結束,容器的網(wǎng)絡和命名空間,以及容器鏡像的傳輸和存儲。containerd對外開放gRPC API,默認通過監(jiān)聽套接字來和dockerd進行交互,在接收到dockerd的gRPC請求后,containerd分析請求內容,根據(jù)內容的不同(如鏡像處理或者容器實例創(chuàng)建)將其分配到對應的服務中。containerd進程是在初始化containerd服務的時候被創(chuàng)建并一直在后臺運行,該進程與dockerd進程是一對一的關系。containerd與containerd-shim是一對多的關系,負責所有containerd-shim進程的創(chuàng)建和管理,并使用ttrpc協(xié)議進行通信。

4) containerd-shim負責使用runc創(chuàng)建并啟動容器實例,并在啟動完成runc退出后接管容器實例,同時負責容器實例的標準輸入輸出以及打開文件,從而在containerd或dockerd意外退出的時候保證容器實例的正常運行。containerd-shim是容器實例進程的父進程,每個容器實例都與一個containerd-shim進程一一對應。

4 DoS攻擊分析

本文設計了一種針對Docker組件的DoS攻擊方法。受到Gao等[3]利用宿主操作系統(tǒng)的journald進程進行DoS攻擊的啟發(fā),本文嘗試了多種在容器實例內可能會觸發(fā)宿主操作系統(tǒng)進行日志記錄的操作,發(fā)現(xiàn)當使用printf在容器實例內持續(xù)輸出數(shù)據(jù)到stdout時,會引發(fā)Docker各組件消耗大量CPU,從而造成DoS攻擊。本節(jié)首先介紹DoS攻擊的設置,然后給出攻擊結果,最后對攻擊成功的原因進行詳細分析。

4.1 攻擊設置

本文在Docker上測試了該DoS攻擊。測試使用的Docker版本為19.03.9,宿主機操作系統(tǒng)為Ubuntu 18.04.4 LTS,內核版本為 4.15.0,物理主機型號為Dell Opti-Plex-7060,CPU型號為 Intel i7-8700 (6核12線程),內存大小為16 GB。

圖2 DoS攻擊中各組件CPU使用率

Figure 2 The CPU utilization of components in the DoS attack

圖3 Docker組件復制容器實例stdio原理分析(以stdout為例)

Figure 3 Docker components copy container instance’s stdio (stdout for example)

本文使用docker run命令創(chuàng)建并啟動容器實例,命令的參數(shù)包括:①-it參數(shù),用于開放容器實例的stdin并分配tty設備用于終端交互;②--cpuset-cpus="0"參數(shù),用于限制容器實例運行在單個CPU核上,從而該容器實例中運行的所有進程占用CPU至多為單核100%(宿主機CPU包含12核,總CPU資源為1200%);③容器鏡像名稱,本文使用Docker Hub中的Ubuntu官方鏡像來創(chuàng)建容器;④在容器中運行的命令,本文指定在容器中運行攻擊程序(使用printf向stdout持續(xù)輸出數(shù)據(jù))。除了以上參數(shù),本文還通過--log-driver參數(shù)來控制Docker容器日志記錄其是否啟用,并測試了在啟用日志和禁用日志的配置下DoS攻擊的效果。

4.2 攻擊結果

測試結果顯示該DoS攻擊可以成功觸發(fā)Docker組件消耗大量CPU。圖2展示了在DoS攻擊中,Docker各組件的CPU使用率,可以看出在啟用日志和禁用日志兩種配置下的Docker各個組件總的CPU使用率分別為607.1%和703.5%(宿主機總CPU資源為1200%),遠高于100%的容器實例CPU限制。在啟用日志記錄的配置下,dockerd進程的CPU使用率最高(240.7%),這是因為dockerd不僅將容器的stdout傳遞給docker-cli,還將這些數(shù)據(jù)記錄到日志文件中。禁用日志記錄后,由于不再進行日志文件的讀寫,反而加快了Docker組件對容器stdout復制的速度,從而使各組件的CPU使用率總和升高。

4.3 原理分析

為了分析在DoS攻擊測試中Docker組件大量消耗CPU的具體原因,本文使用pprof動態(tài)分析了Docker各組件內函數(shù)在被攻擊時的CPU使用量,結果顯示docker-cli、dockerd和containerd-shim內CPU占用率最高的函數(shù)分別為io.Copy、io.CopyBuffer和io.CopyBuffer,本文稱其為特征函數(shù),進一步分析之后發(fā)現(xiàn)這些特征函數(shù)都位于特殊的、可被反復觸發(fā)的goroutine中。goroutine是一種輕量級的線程[16],與其他線程并發(fā)運行。一個Go應用程序通常同時運行多個執(zhí)行不同任務的goroutine,這些goroutine可以被自動觸發(fā)。

根據(jù)pprof中統(tǒng)計函數(shù)的CPU占用率和調用關系,發(fā)現(xiàn)在基于printf的DoS攻擊中,Docker不同組件中的goroutine被攻擊程序不斷觸發(fā),其內部的特征函數(shù)(docker-cli中的io.Copy,dockerd和containerd-shim中的io.CopyBuffer)頻繁地進行數(shù)據(jù)讀寫,導致消耗大量CPU,使DoS攻擊成功。在此基礎上,本文對該goroutine進行了分析,發(fā)現(xiàn)該goroutine中的特征函數(shù)被用于復制容器實例的stdout,一旦容器實例產生stdout輸出,該goroutine中的特征函數(shù)就會被觸發(fā),對stdout中的輸出進行復制,因此攻擊者可通過在容器實例內部持續(xù)輸出stdout觸發(fā)各組件goroutine中的特征函數(shù)頻繁地進行數(shù)據(jù)讀寫,達到對組件的DoS攻擊。由此可見,利用組件間stdio復制進行DoS攻擊需滿足兩個條件:①有goroutine被創(chuàng)建;②goroutine中使用特征函數(shù)(io.Copy或io.CopyBuffer)進行stdio復制。正是Docker組件進程中存在此類goroutine,攻擊者才能對其進行DoS攻擊。

通過分析Docker各組件,本文發(fā)現(xiàn)若要復制容器實例的stdout,就需要在容器實例初始化階段創(chuàng)建新的goroutine,并在其內部調用特征函數(shù)進行容器實例stdout輸出的復制。圖3分別展示了Docker各組件在容器實例創(chuàng)建階段和容器實例運行階段對goroutine和stdout復制的操作。當用戶在終端執(zhí)行docker start命令時,Docker各個組件協(xié)同創(chuàng)建新的容器實例,同時創(chuàng)建goroutine并在其內部調用特征函數(shù)負責復制容器實例的stdout,本文將docker-cli、dockerd和containerd-shim創(chuàng)建的用于復制容器實例stdout的goroutine分別稱為goroutine1、goroutine2和goroutine3(goroutine1內調用io.Copy,goroutine2和goroutine3內調用io.CopyBuffer),如圖3(a)所示。

容器實例運行階段,Docker各組件采用套接字、命名管道、匿名管道和ptmx/pts設備對容器實例的stdout進行中繼,如圖3(b)所示。containerd-shim根據(jù)容器實例初始化的配置參數(shù)(如-it或-d等)來決定和容器實例的通信方法:如果使用-it參數(shù),則使用ptmx/pts設備進行交互,容器實例將stdout寫入pts設備后,containerd-shim從ptmx設備中讀出數(shù)據(jù);若使用-d參數(shù),containerd-shim與容器實例通過匿名管道進行通信。containerd-shim把容器實例的stdout通過命名管道傳遞給dockerd,dockerd將獲得的數(shù)據(jù)通過套接字轉發(fā)給docker-cli。

容器實例stdout未產生數(shù)據(jù)時,特征函數(shù)處于阻塞狀態(tài)。在運行階段,容器實例內部產生stdout后,如printf DoS攻擊中的Hello輸出,containerd-shim內goroutine3中的io.CopyBuffer函數(shù)被觸發(fā),先讀出容器實例的stdout(通過ptmx設備或匿名管道),再寫入和dockerd共享的命名管道,如圖3(b)所示,進而觸發(fā)dockerd中的goroutine2將數(shù)據(jù)寫入和docker-cli通信的套接字中,最終觸發(fā)docker-cli中負責復制stdout的goroutine1,把數(shù)據(jù)輸出到用戶終端上,用戶即可觀察到該輸出,即字符串“Hello!”。綜上可知,如果在容器實例創(chuàng)建階段,Docker組件創(chuàng)建了負責復制stdio的goroutine,攻擊者可以在容器運行階段,通過不斷輸出到stdout,觸發(fā)各組件goroutine中的特征函數(shù)不斷地進行數(shù)據(jù)讀寫,從而大幅提高各組件的CPU使用率,造成對于宿主機CPU資源的DoS攻擊。

目前常用的資源限制技術cgroups無法通過限制CPU使用量抵御針對Docker組件間stdio的DoS攻擊。cgroups限制CPU使用量往往只針對容器實例進程,對其他Docker組件則不作限制,因此組件內goroutine可消耗的CPU資源并無上限。更大的問題是,所有的容器實例共享同一個dockerd進程,因此現(xiàn)有cgroups技術無法區(qū)分、限制單個容器實例所引發(fā)的dockerd的CPU消耗。所以現(xiàn)有技術無法通過限制CPU來防護針對Docker組件間stdio的DoS攻擊。

5 分析框架設計與實現(xiàn)

從攻擊原理分析中,可知在容器實例創(chuàng)建階段,Docker各個組件創(chuàng)建的使用特征函數(shù)對stdout進行復制的goroutine會引發(fā)DoS攻擊,而現(xiàn)有的cgroups技術并不能防護此類DoS攻擊,因此本文提出一個Docker組件的靜態(tài)分析框架,使用靜態(tài)分析方法來找出所有能創(chuàng)建此類goroutine的路徑,然后在不同組件間分析路徑的連接,最終找到所有能觸發(fā)此類路徑的Docker命令。

本文提出的Docker組件調用路徑靜態(tài)分析框架如圖4所示,使用Docker各個組件的源代碼作為輸入。分析框架首先使用gollvm將Docker各組件源代碼編譯為LLVM IR,然后對每個組件IR中的接口成員函數(shù)進行解析,為所有接口成員函數(shù)的間接調用語句建立調用表,進而利用特征函數(shù)(docker-cli對應io.Copy,dockerd和containerd-shim對應io.CopyBuffer)逐個分析各個組件,得到每個組件內部創(chuàng)建goroutine并調用特征函數(shù)的路徑,最后使用Docker組件間通信協(xié)議對不同組件內的路徑進行連接,得到從Docker命令輸入該組件創(chuàng)建goroutine的完整路徑。

圖4 Docker組件函數(shù)調用路徑靜態(tài)分析框架

Figure 4 Static analysis framework for function call paths in Docker components

雖然基本思路簡單,但實現(xiàn)該分析框架需要解決兩個技術挑戰(zhàn)。

第一,在分析Docker調用路徑時,需要構建完整的程序控制流圖(CFG,control flow graph),然而由于Docker組件使用Go語言編寫,其內大量使用了接口,對接口成員函數(shù)的調用最終通過間接調用來實現(xiàn),因此無法由調用語句分析得到目標函數(shù),導致無法形成完整的調用路徑,無法構建完整的程序控制流圖。為了解決該問題,本文設計了接口成員函數(shù)解析方法,利用數(shù)據(jù)流分析和函數(shù)類型匹配找到了接口成員函數(shù)的具體實現(xiàn),進而建立接口成員函數(shù)調用表,使在進行組件分析時可以得到完整路徑。

第二,由于用戶只能通過Docker命令和docker-cli以及后續(xù)的各個組件進行交互,因此最終路徑應為從Docker命令開始到組件內創(chuàng)建goroutine結束的跨組件路徑,然而LLVM只能分析單個組件內的調用路徑,不同組件之間的路徑無法通過組件IR分析得到。為了解決該問題,本文提出了跨組件路徑連接方法,根據(jù)組件兩兩交互時使用的通信函數(shù)和對應的特征字段,通過特征字段和函數(shù)的匹配完成不同組件的路徑連接。

5.1 接口成員函數(shù)解析

在對Docker各個組件進行分析時,需要通過分析函數(shù)的調用關系來構建完整的程序控制流圖,后續(xù)可以在控制流圖進行路徑遍歷,進而找到完整的調用路徑。因此完整的程序控制流圖對后續(xù)分析至關重要。在分析Docker組件時,由于Docker組件使用Go語言編寫,大量使用接口,而接口成員函數(shù)的調用往往通過間接調用實現(xiàn)。無法通過解析調用語句得到目標函數(shù),這導致大量的路徑分析在接口成員函數(shù)處斷裂,程序控制流圖不完整,嚴重影響分析效果。

圖5 Go語言interface在LLVM IR中的實現(xiàn)

Figure 5 Implementation of Go interface in LLVM IR

為了解決這個問題,本文提出結合數(shù)據(jù)流分析和函數(shù)類型來對接口成員函數(shù)的目標函數(shù)進行解析。圖5以一個簡單的Go語言程序為例,介紹一個接口成員函數(shù)調用的全過程。圖5(a)中定義了接口I(第3~5行),該接口內有兩個成員函數(shù)Get和Set;同時程序中的結構體A實現(xiàn)了接口I,包含Get函數(shù)和Set函數(shù)(圖5(a)第8~18行)。main函數(shù)(第24行)中創(chuàng)建了結構體A的實例a,并將其作為參數(shù)傳入函數(shù)f(第20行)。函數(shù)f中調用了接口I的實例i的成員函數(shù)Set,即a.Set。圖5(b)展示了源代碼編譯出的LLVM IR,本文將其對接口成員函數(shù)調用實現(xiàn)分為3步:首先,創(chuàng)建全局變量@pimt...main.A存放所有結構體A實現(xiàn)的接口I的成員函數(shù),其中結構體A實現(xiàn)的Get函數(shù)(@main.A.Get)為@pimt...main.A中的第二個成員變量,對應偏移量為1,Set函數(shù)(@main.A.Set)對應的偏移量為2;其次,在接口實例被創(chuàng)建的函數(shù)中,如本例子中@main.main函數(shù),創(chuàng)建%I.0類型的變量%i.addr,并將全局變量@pimt...main.A存入%i.addr中偏移量為0的成員變量中;最后,在接口成員函數(shù)的調用時(圖5(b)第18~25行),先從%I.0類型的變量%i.addr中取出其偏移量為0的成員變量,再從該成員變量中取它的偏移量為2的成員變量,最終得到的變量%.field.ld.2中存放的是結構體A實現(xiàn)的Set函數(shù)(@main.A.Set)的地址。

基于以上分析,本文提出使用數(shù)據(jù)流分析和函數(shù)類型匹配的方法尋找接口成員函數(shù)的目標函數(shù)。首先,找到所有存放接口成員函數(shù)的全局變量(如圖5(b)中的@pimt...main.A),由于這類全局變量具有統(tǒng)一的命名規(guī)則(變量名以imt或pimt開頭),因此可以通過匹配pimt和imt關鍵字來找到它們。在找到所有這類全局變量后,根據(jù)全局變量的初始化語句確定每個接口成員函數(shù)對應的偏移量,如@main.A.Get和@main.A.Set分別對應偏移量1和2。然后,利用LLVM編譯器提供的“定義?調用”鏈來遍歷這類全局變量被store指令使用的位置(如圖5(b)第12行),通過分析store指令中存放對象(圖中為%field.15)的來源可知,該全局變量被存放到了某類型(圖中為%I.0)變量中的特定偏移量(圖中為0)處,從而明確了類型%I.0與全局變量@pimt...main.A的關系。最后,對所有間接調用語句(圖5(b)第25行)進行分析,查找被調用變量(圖中為%.field.ld.2)的來源,如果是接口成員函數(shù)的調用,則會有類似圖5(b)中第20~23行的語句,從類型%I.0的變量中連續(xù)取了兩次成員變量,第一次使用偏移量0取出了全局變量@pimt...main. A,第二次使用偏移量2取出接口成員函數(shù)@main.A.Set,如果有多個結構體類型實現(xiàn)了接口I,則認為此處調用點可調用到所有Set函數(shù)的實現(xiàn)。

5.2 組件內函數(shù)調用路徑分析

在對接口成員函數(shù)目標函數(shù)解析后,本文在各個組件的控制流圖上進行分析,找出各個組件內的包含stdio復制的goroutine創(chuàng)建路徑。本文設計并實現(xiàn)了組件內函數(shù)調用路徑分析Pass[17]。該Pass以Docker組件的LLVM IR和組件內負責容器實例stdio復制的特征函數(shù)(docker-cli中使用io.Copy,dockerd和containerd-shim中使用io.CopyBuffer)為輸入,輸出該組件內會創(chuàng)建goroutine并調用特征函數(shù)的路徑。

最終的Pass流程如圖6所示,具體步驟如下。①在接收到特征函數(shù)名稱和Docker組件LLVM IR后,首先根據(jù)特征函數(shù)名稱,如“io.Copy”或“io.CopyBuffer”,遍歷組件IR,找到和該名稱對應的函數(shù)(LLVM::Function),將其記錄下來作為待搜索函數(shù)。②判斷待搜索函數(shù)是否為接口成員函數(shù),由于5.1節(jié)中解析了組件IR中所有的接口成員函數(shù),因此可以由檢查待搜索函數(shù)是否位于接口成員函數(shù)調用表中來判斷,若在表中,說明待搜索函數(shù)為接口成員函數(shù),直接從表中取出所有調用該待搜索函數(shù)的函數(shù);若不在表中,則說明待搜索函數(shù)不是接口成員函數(shù),此時使用LLVM“定義?調用”鏈找到所有待搜索函數(shù)的調用處,由調用點可推斷出調用函數(shù)。③若第②步沒有得到任何調用函數(shù),說明目前找到的調用路徑已經完整,即可跳到第⑤步進行路徑輸出;否則,對所有的調用函數(shù)進行分析,判斷待搜索函數(shù)是否在新創(chuàng)建的goroutine中被調用。goroutine的創(chuàng)建在LLVM IR中是以@__go_go函數(shù)調用實現(xiàn)的,因此要判斷待搜索函數(shù)是否在新創(chuàng)建的goroutine中被調用,只要分析在調用函數(shù)內,待搜索函數(shù)的地址是否被存入一個變量并作為@__go_go函數(shù)的參數(shù)被調用即可。④若待搜索函數(shù)處于調用函數(shù)新創(chuàng)建的goroutine中,則將該路徑標記為創(chuàng)建goroutine的路徑,否則不做任何操作。接著對所有的調用函數(shù),重復步驟②至步驟④,直到無法找到任何調用函數(shù)為止。⑤對路徑進行判斷,如果路徑被標記為創(chuàng)建goroutine的路徑,說明該路徑中創(chuàng)建了新的goroutine并調用了特征函數(shù),符合分析的目標,將其輸出即可。按照以上步驟最終可以得到該組件內所有創(chuàng)建goroutine并調用特征函數(shù)的路徑。

圖6 Docker組件內函數(shù)調用路徑分析Pass流程

Figure 6 Flow chart of Pass analysis for function call path in Docker components

5.3 跨組件路徑連接

5.2節(jié)實現(xiàn)的LLVM Pass找到的是Docker單個組件內的路徑,本節(jié)通過對Docker各組件的通信方法進行分析,整理出了每兩個組件之間通信函數(shù)和交互特征,使用字段匹配、函數(shù)匹配等方式成功連接各組件相關的函數(shù)調用路徑。

docker-cli與dockerd的交互函數(shù)如圖7所示。docker-cli通過向dockerd發(fā)送HTTP請求來完成和dockerd的交互,而dockerd會根據(jù)接收到的HTTP請求字段來調用對應的處理函數(shù)。圖7(a)展示了docker-cli中發(fā)送啟動容器實例請求的函數(shù)ContainerStart,該函數(shù)將特定的字段“/containers//start”作為HTTP請求中path字段的值,并調用post函數(shù)將該HTTP請求發(fā)送至dockerd。圖7(b)展示了dockerd中調用initeRoutes初始化HTTP請求Router的過程,該Router根據(jù)HTTP請求的path字段來指定對應的處理函數(shù),圖中的postContainerStart函數(shù)是處理容器實例啟動請求的函數(shù),函數(shù)中對應的path字段的值為“/containers/{name:.*}/start”。該字段與docker-cli中發(fā)送的HTTP請求的path字段值相對應。由此可得,dockerd中postContainerStart可以被docker-cli中的ContainerStart函數(shù)觸發(fā),從而完成跨組件調用。因此,本文通過匹配HTTP請求中的path字段值,來完成docker-cli與dockerd的路徑連接。

dockerd與containerd、containerd與containerd- shim的路徑連接與上文介紹的方法類似。dockerd通過gRPC和containerd進行通信,dockerd向containerd發(fā)送gRPC請求,如圖3(a)所示,通過請求中的method字段指定相應的gRPC響應,如dockerd中tasksClient.Start函數(shù)將“/containerd. services.tasks.v1.Tasks/Start”作為gRPC請求中的method字段,而containerd收到該請求后,調用_Tasks_Start_Handler函數(shù)對其進行響應,并且_Tasks_Start_Handler函數(shù)同樣包含上述字段,從而可以通過匹配該字段來完成dockerd和containerd的路徑連接。

圖7 docker-cli 與 dockerd 的交互函數(shù)

Figure 7 Interact functions between docker-cli and dockerd

containerd通過ttrpc和containerd-shim進行通信,如圖3(a)所示。containerd通過請求中的service字段和method字段來指定ttrpc響應函數(shù),如containerd調用shimClient.Start函數(shù)將“containerd.runtime.linux.shim.v1.Shim”作為service字段、“Start”作為method字段組成ttrpc請求包發(fā)送給containerd-shim。containerd-shim在初始化階段調用RegisterShimService函數(shù)注冊所有ttrpc服務,同時按照service字段和method字段來指定響應函數(shù),在這個例子中,shimClient.Start的響應函數(shù)為local.Start函數(shù)。因此在連接containerd和containerd-shim的路徑時,可以通過service字段和method字段來匹配對應的請求和響應函數(shù)來完成跨組件路徑連接。

通過匹配HTTP、gRPC和ttrpc請求包中的特定字段,可以建立組件間的函數(shù)調用關系,從而完成docker-cli與dockerd、dockerd與containerd、containerd與containerd-shim中的調用路徑連接。通過路徑連接可以得到goroutine1、goroutine2、goroutine3對應的完整的創(chuàng)建路徑,以及觸發(fā)這些goroutine創(chuàng)建的Docker命令。

6 實驗

本節(jié)使用Docker測試實現(xiàn)的靜態(tài)分析框架原型。在測試中,成功將Docker各組件編譯為LLVM IR,并且使用靜態(tài)分析框架原型成功地分析出了各組件內goroutine的創(chuàng)建路徑,包含docker-cli的goroutine1,dockerd的goroutine2和containerd-shim的goroutine3,然后通過跨組件路徑連接得到了這些goroutine的創(chuàng)建對應在docker-cli中的命令,最后驗證了這些路徑能否成功被觸發(fā)并創(chuàng)建相應的goroutine進行容器實例的stdio復制。

6.1 實驗設置

本文分析的Docker版本為Docker CE 19.03.9,對應的Docker各組件版本如表1第2列所示。使用的LLVM編譯器版本為11.0.0git,gollvm版本為 go1.14.2。驗證路徑時使用的物理設備和系統(tǒng)環(huán)境與第4.1節(jié)中介紹的相同。

表1 Docker各組件對應的LLVM IR

在源代碼基礎上,本文需要將各組件編譯為LLVM IR。首先,設置gollvm為默認Go編譯器,使用go build命令編譯組件源碼,命令中需要使用-x-work參數(shù)記錄編譯過程中的所有編譯指令;然后,將編譯指令中的生成對象替換為LLVM IR文件,再次執(zhí)行,得到該組件內所有package對應的LLVM IR;最后,使用llvm-link將所有包的LLVM IR鏈接起來,得到該組件對應的LLVM IR。本文使用代碼行數(shù)統(tǒng)計工具cloc來統(tǒng)計各個組件的源代碼行數(shù)。實驗中Docker各個組件的版本、源代碼行數(shù)、對應的LLVM IR大小如表1所示。

6.2 實驗結果

實驗結果主要分為兩部分:各個組件內路徑統(tǒng)計和跨組件路徑統(tǒng)計。Docker各個組件路徑分析結果如表2所示。docker-cli、dockerd以及containerd-shim可創(chuàng)建包含stdio復制的goroutine路徑分別有12條、71條和30條。另外,containerd經過分析不存在可被Docker命令觸發(fā)的容器實例的stdio復制路徑。

表2 Docker各組件路徑分析結果

跨組件路徑分析結果如表3所示,本文實現(xiàn)的靜態(tài)分析框架原型分析出docker-cli中通過命令可以創(chuàng)建goroutine1、goroutine2和goroutine3的路徑分別有12條、13條和9條,總計34條。本文同時對所有分析出來的跨組件路徑進行了動態(tài)運行驗證,能夠成功被用戶輸入的docker-cli命令觸發(fā)并創(chuàng)建對應goroutine的路徑分別為8條、8條和6條,總計22條,如表3第3列所示。對比第3列和第2列,可以得出靜態(tài)分析的準確率分別為66.7%、61.5%和66.7%。

表3 跨組件路徑分析結果

在驗證路徑時,本文發(fā)現(xiàn)Docker存在Healthcheck機制,當創(chuàng)建容器鏡像時使用的Dockerfile中包含HEALTHCHECK命令時,Docker會定時檢查以此鏡像啟動的容器實例是否死鎖,而檢查過程中會創(chuàng)建復制容器實例的stdio的goroutine(goroutine2和goroutine3),但此處的goroutine會在檢查結束之后立刻終止,無法被用來做DoS攻擊。因此,所有和該機制有關的路徑(如docker unpause等命令觸發(fā)的路徑)都不視為驗證成功的路徑,因為它們并沒有主動創(chuàng)建goroutine進行stdio復制,即使觸發(fā)了容器實例的Healthcheck機制,也無法被用來做DoS攻擊。

在動態(tài)運行驗證時可被成功觸發(fā)的路徑中,有部分路徑可以由同一個Docker命令(命令參數(shù)也相同)觸發(fā),運行該命令可同時觸發(fā)多個goroutine的創(chuàng)建。其中,docker start -it命令可以同時觸發(fā)docker-cli中goroutine1、goroutine2、goroutine3對應的路徑,因而在運行該命令后可同時創(chuàng)建這3種goroutine。圖8展示了該命令可以觸發(fā)的路徑。圖左側為容器實例初始化階段,docker-cli、dockerd和containerd-shim分別創(chuàng)建了goroutine1、goroutine2和goroutine3具體的函數(shù)調用鏈。圖右側展示了容器實例運行階段,當有stdout產生時,各組件的goroutine會把數(shù)據(jù)復制最終寫入用戶終端,因而容器實例內部的攻擊者可通過在容器實例內持續(xù)輸出數(shù)據(jù)到stdout來進行對Docker組件的DoS攻擊。可以同時觸發(fā)3種goroutine創(chuàng)建的Docker命令和參數(shù)組合,共計6種。

值得注意的是,在執(zhí)行一些Docker命令后(如docker run -d),僅有goroutine2和goroutine3被創(chuàng)建,當攻擊者在容器實例內使用printf進行DoS攻擊時,goroutine2和goroutine3仍可被成功觸發(fā)并消耗大量CPU,但此時Docker組件的CPU消耗總和小于3種goroutine都被創(chuàng)建時進行DoS攻擊后的CPU消耗。

7 結束語

本文提出了一種針對Docker組件的DoS攻擊方法,通過在容器實例內部使用printf頻繁輸出數(shù)據(jù)到stdout令Docker組件消耗大量CPU造成DoS攻擊。經過對該攻擊原理的分析,本文發(fā)現(xiàn)Docker組件在容器實例初始化階段會創(chuàng)建新的goroutine,并在其內部調用特征函數(shù),如io.Copy或io.CopyBuffer,對容器實例的stdio進行復制,因此這些goroutine會被printf DoS攻擊不斷觸發(fā)消耗大量CPU而使DoS攻擊成功。當前cgroups技術并不能防御此類DoS攻擊。

圖8 Docker組件stdio復制觸發(fā)路徑(以docker start為例)

Figure 8 Docker components stdio copy trigger path(take docker start for example)

為了分析所有可能導致DoS攻擊的路徑,本文提出使用靜態(tài)分析的方法來系統(tǒng)化地分析Docker組件,使用LLVM編譯器分析Docker各組件創(chuàng)建goroutine并調用特征函數(shù)進行容器實例stdio復制的路徑。本文設計并實現(xiàn)了接口成員函數(shù)解析、組件內函數(shù)調用路徑分析和跨組件路徑連接等技術,實現(xiàn)了靜態(tài)分析框架原型系統(tǒng),并且在最新Docker版本上進行了測試。測試結果顯示靜態(tài)分析框架原型系統(tǒng)成功地找出了各組件內創(chuàng)建goroutine的路徑,并通過路徑連接分析出可被 Docker命令觸發(fā)的路徑總計34條,經過動態(tài)驗證,這些路徑中總計22條可成功被Docker命令觸發(fā)并創(chuàng)建對應goroutine。

[1] MERKELD. Docker: lightweight Linux containers for consistent development and deployment[J]. Linux Journal, 2014(239):2.

[2] SEYFRIED S. Resource management in Linux with control groups[C]//Proceedings of the Linux-Kongress. 2010.

[3] GAO X, GU Z S, LI Z F, et al. Houdini′s escape: breaking the resource rein of Linux control groups[C]//Proceedings of the 2019 ACM SIGSAC Conference on Computer and Communications Security. 2019: 1073-1086.

[4] BUI T. Analysis of docker security[J]. arXiv preprint arXiv: 1501.02967, 2015.

[5] GUPTA U. Comparison between security majors in virtual machine and Linux containers[J]. arXiv preprint arXiv:1507.07816, 2015.

[6] BACIS E, MUTTI S, CAPELLI S, et al. Docker policy modules: mandatory access control for docker containers[C]//2015 IEEE Conference on Communications and Network Security (CNS). 2015: 749-750.

[7] SMALLEY S, VANCE C, SALA-MON W. Implementing selinux as a linux security module[J]. NAI Labs Report, 2001, 1(43): 139.

[8] COMBE T, MARTIN A, PIETRO R. To docker or not to docker: a security perspective[J]. IEEE Cloud Computing, 2016, 3(5): 54-62.

[9] CHELLADHURAI J, CHELLIAH P R, KUMAR A. Securing Docker containers from denial of service (DoS) attacks[C]//2016 IEEE International Conference on Services Computing (SCC). 2016: 856-859.

[10] SHU R, GU X H, ENCK W L. A study of security vulnerabilities on docker hub[C]//Proceedings of the Seventh ACM on Conference on Data and Application Security and Privacy. 2017: 269-280.

[11] YASRAB R. Mitigating docker security issues[J]. arXiv preprint arXiv:1804.05039, 2018.

[12] JIAN Z Q, CHEN L. A defense method against docker escape attack[C]//Proceedings of the 2017 International Conference on Cryptography, Security and Privacy. 2017: 142-146.

[13] ROSENR. Namespaces and cgroups, the basis of Linux containers[C]//Proceedings of the NetDev. 2016.

[14] 王鵑, 胡威, 張雨菡, 等. 基于Docker的可信容器[J]. 武漢大學學報(理學版), 2017, 63(2): 102-108.

WANG J, HU W, ZHANG Y H, et al. Trusted container based on Docker[J]. Journal of Wuhan University (Natural Science Edition), 2017, 63(2): 102-108.

[15] LIN X, LEI L G, WANG Y W, et al. A measurement study on linux container security: attacks and countermeasures[C]//Proceedings of the 34th Annual Computer Security Applications Conference. 2018: 418-429.

[16] PRABHAKARR, KUMARR. Concurrent programming with go[R]. 2011.

[17] LOPES B C, AULERR.Getting started with LLVM core libraries[M]. Packt Publishing Ltd, 2014.

論文引用格式:周天昱, 申文博, 楊男子, 等. Docker組件間標準輸入輸出復制的DoS攻擊分析[J]. 網(wǎng)絡與信息安全學報, 2020, 6(6): 45-56.

ZHOU T Y, SHEN W B, YANG N Z, et al. The analysis of DoS attacks on Docker inter-component stdio copy[J]. Chinese Journal of Network and Information Security, 2020, 6(6): 45-56.

Analysis of DoS attacks on Docker inter-component stdio copy

ZHOU Tianyu1,2, SHEN Wenbo2, YANG Nanzi3,LI Jinku3,QIN Chenggang4,YU Wang4

1. Zhejiang University NGICS Platform, Hangzhou 310027, China 2. School of Cyber Science and Technology, Zhejiang University, Hangzhou 310027, China 3. School of Cyber Engineering, Xidian University, Xi'an 710071, China 4. Ant Financial Services Group, Hangzhou 310000, China

In recent years, Docker has been widely deployed due to its flexibility and high scalability. However, its modular design leads to the DoS attacks on inter-component communication. A new DoS attack that outputs to stdout, causing high CPU usages among different Docker components. Analysis shows that the stdout output triggers the goroutines of Docker components. To find all goroutines setup paths, using the static analysis method to analyze the Docker components systematically was proposed. A static analysis framework was designed and implemented, and evaluated on Docker source code. The results show that static analysis framework finds 34 paths successfully, while 22 of them are confirmed by runtime verification.

container, Docker components, DoS attack, static analysis

s: Leading Innovative and Entrepreneur Team Introduction Program of Zhejiang Province (2018R01005), The Key R&D Program of Shaanxi Province (2019ZDLGY12-06), Fundamental Research Funds for the Central Universities(Zhejiang University NGICS Platform

TP393

A

10.11959/j.issn.2096?109x.2020074

周天昱(1995? ),男,浙江杭州人,浙江大學碩士生,主要研究方向為容器安全。

申文博(1989? ),男,浙江大學研究員、博士生導師,主要研究方向為操作系統(tǒng)安全、容器安全、軟件及系統(tǒng)攻防、硬件安全、程序分析。

楊男子(1996? ),男,陜西咸陽人,西安電子科技大學碩士生,主要研究方向為容器安全。

李金庫(1976? ),男,河北保定人,西安電子科技大學教授、博士生導師,主要研究方向為系統(tǒng)與網(wǎng)絡安全、移動安全、云計算及其安全。

秦承剛(1983? ),男,江蘇徐州人,主要研究方向為操作系統(tǒng)、系統(tǒng)安全。

喻望(1986? ),男,重慶人,主要研究方向為Linux內核、安全容器技術。

2020?07?01;

2020?09?24

申文博,shenwenbo@zju.edu.cn

浙江省引進培育領軍型創(chuàng)新創(chuàng)業(yè)團隊(2018R01005);陜西省重點研發(fā)計劃基金(2019ZDLGY12-06);中央高?;究蒲袠I(yè)務費專項基金(浙江大學NGICS大平臺)

猜你喜歡
分析
禽大腸桿菌病的分析、診斷和防治
隱蔽失效適航要求符合性驗證分析
電力系統(tǒng)不平衡分析
電子制作(2018年18期)2018-11-14 01:48:24
電力系統(tǒng)及其自動化發(fā)展趨勢分析
經濟危機下的均衡與非均衡分析
對計劃生育必要性以及其貫徹實施的分析
GB/T 7714-2015 與GB/T 7714-2005對比分析
出版與印刷(2016年3期)2016-02-02 01:20:11
中西醫(yī)結合治療抑郁癥100例分析
偽造有價證券罪立法比較分析
在線教育與MOOC的比較分析
主站蜘蛛池模板: 午夜影院a级片| 青青青国产在线播放| 国产办公室秘书无码精品| 欧美天堂在线| 精品综合久久久久久97超人该| 日本影院一区| 国产交换配偶在线视频| 国产午夜无码片在线观看网站| 亚洲 欧美 偷自乱 图片| 无码中文AⅤ在线观看| 国产欧美日韩91| 国产成人亚洲综合A∨在线播放| 少妇露出福利视频| 国产日韩精品欧美一区喷| 国精品91人妻无码一区二区三区| 国产chinese男男gay视频网| 日韩福利视频导航| 亚洲午夜国产片在线观看| 91久久国产热精品免费| 亚洲色图欧美一区| 精品国产欧美精品v| 亚洲第一成年网| 免费一级全黄少妇性色生活片| 亚洲无限乱码一二三四区| 午夜视频www| 天堂av综合网| 欧美一道本| 亚洲精品手机在线| 亚洲精品无码AⅤ片青青在线观看| 黄色网页在线播放| 91精品视频播放| 四虎永久在线视频| 国产日韩欧美中文| 欧美成人手机在线观看网址| 日韩国产 在线| 亚洲中文久久精品无玛| 亚洲水蜜桃久久综合网站| 精品福利网| 97色婷婷成人综合在线观看| 九月婷婷亚洲综合在线| 亚洲妓女综合网995久久| 日本欧美一二三区色视频| 久久精品这里只有国产中文精品| 99er这里只有精品| 亚洲国产日韩欧美在线| 人人爽人人爽人人片| 欧美性猛交一区二区三区| AV在线天堂进入| 色综合狠狠操| 精品伊人久久久香线蕉 | 区国产精品搜索视频| 免费中文字幕一级毛片| 日本a∨在线观看| 五月婷婷中文字幕| 一级毛片在线免费看| 亚洲娇小与黑人巨大交| 日本在线亚洲| 国内精自视频品线一二区| 中文无码日韩精品| 99久久无色码中文字幕| 国产在线自乱拍播放| 国产精品网址在线观看你懂的| 91高清在线视频| 亚洲乱亚洲乱妇24p| 2021亚洲精品不卡a| 无码福利日韩神码福利片| 欧美中文字幕一区| 欧美精品1区2区| 亚洲天堂久久久| 精品无码视频在线观看| 亚洲av无码牛牛影视在线二区| 欧美伦理一区| 亚洲AⅤ波多系列中文字幕| 国产高清毛片| 又猛又黄又爽无遮挡的视频网站| 免费99精品国产自在现线| 中字无码精油按摩中出视频| 在线观看亚洲天堂| 亚洲欧美日韩中文字幕在线一区| 最新亚洲人成网站在线观看| 午夜丁香婷婷| 久久伊人操|