亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于異構(gòu)觀測(cè)鏈的容器逃逸檢測(cè)方法

        2023-02-20 13:37:02張?jiān)茲?/span>方濱興杜春來王忠儒崔志堅(jiān)宋首友
        通信學(xué)報(bào) 2023年1期
        關(guān)鍵詞:進(jìn)程檢測(cè)

        張?jiān)茲?,方濱興,2,杜春來,王忠儒,崔志堅(jiān),宋首友,5

        (1.北京郵電大學(xué)網(wǎng)絡(luò)空間安全學(xué)院,北京 100876;2.廣州大學(xué)網(wǎng)絡(luò)空間先進(jìn)技術(shù)研究院,廣東 廣州 510006;3.北方工業(yè)大學(xué)信息學(xué)院,北京 100144;4.中國網(wǎng)絡(luò)空間研究院信息化研究所,北京 100010;5.北京丁??萍加邢薰荆本?100081)

        0 引言

        在數(shù)字經(jīng)濟(jì)背景下,云計(jì)算被寫入《中華人民共和國國民經(jīng)濟(jì)和社會(huì)發(fā)展第十四個(gè)五年規(guī)劃和2035 年遠(yuǎn)景目標(biāo)綱要》。中國信息通信研究院數(shù)據(jù)顯示,預(yù)計(jì)到2024 年,我國云市場(chǎng)規(guī)模將接近7 800 億元。以容器為代表的云原生技術(shù)蓬勃發(fā)展,為云計(jì)算數(shù)字化賦能提供了重要推動(dòng)力,并為軟件開發(fā)和系統(tǒng)運(yùn)維帶來了顛覆性的變革。容器技術(shù)[1]是一種輕量級(jí)的虛擬化技術(shù),可以實(shí)現(xiàn)應(yīng)用程序在虛擬化隔離環(huán)境中的穩(wěn)定運(yùn)行。在傳統(tǒng)操作系統(tǒng)級(jí)別的虛擬化技術(shù)中,每個(gè)實(shí)例都需要運(yùn)行客戶端操作系統(tǒng)的完整副本,因此造成了大量的硬件模擬開銷[2]。容器是進(jìn)程級(jí)的虛擬化,不需要模擬硬件,相比于傳統(tǒng)虛擬化技術(shù)少了很多開銷,從而可以輕量高效地運(yùn)行應(yīng)用程序。容器編排通過微服務(wù)體系結(jié)構(gòu)模式來實(shí)現(xiàn)業(yè)務(wù)流程自動(dòng)化,是大規(guī)模容器應(yīng)用的重要工具。容器編排工具(如 Kubernetets(K8S)[3]和 Docker Swarm[4])的出現(xiàn)極大地方便了容器化應(yīng)用程序的部署、擴(kuò)展和管理。目前,容器技術(shù)已經(jīng)廣泛應(yīng)用于大型互聯(lián)網(wǎng)公司的生產(chǎn)環(huán)境和云服務(wù)供應(yīng)商,如Amazon Fargate、Microsoft Azure Kubernetes 等。

        容器技術(shù)雖然已經(jīng)在實(shí)際生產(chǎn)環(huán)境被廣泛使用,但存在較多潛在的安全威脅,如容器逃逸、資源隔離失效、鏡像安全威脅、橫向移動(dòng)攻擊、拒絕服務(wù)攻擊、運(yùn)行環(huán)境未加固等[5]。其中,容器逃逸直接影響了承載容器的底層基礎(chǔ)設(shè)施的安全性和可用性,進(jìn)而對(duì)生產(chǎn)環(huán)境造成了安全隱患。具體來說,容器逃逸[6]是指攻擊者利用程序、系統(tǒng)的漏洞或缺陷,突破容器與宿主機(jī)之間的隔離機(jī)制,獲得在宿主機(jī)上的命令執(zhí)行能力。目前,導(dǎo)致容器逃逸的主要因素包括配置不當(dāng)、應(yīng)用程序漏洞和系統(tǒng)內(nèi)核漏洞。相比于前兩者,系統(tǒng)內(nèi)核漏洞導(dǎo)致的逃逸危害更大、威脅更廣。這是因?yàn)槿萜髋c宿主機(jī)共用一個(gè)內(nèi)核,攻擊者可以利用內(nèi)核漏洞進(jìn)行攻擊,從而突破隔離“逃逸”至宿主機(jī),對(duì)宿主機(jī)和其他容器造成了極大的安全威脅。因此,如何檢測(cè)利用內(nèi)核漏洞的容器逃逸具有重要的研究意義。由于Docker 是當(dāng)前使用范圍最廣的容器引擎之一,本文專注于檢測(cè)Linux 平臺(tái)下利用內(nèi)核漏洞實(shí)現(xiàn)的Docker 容器逃逸。

        目前,Linux 平臺(tái)下對(duì)利用內(nèi)核漏洞實(shí)現(xiàn)容器逃逸的檢測(cè)方法主要是基于運(yùn)行時(shí)的異常檢測(cè)[7-8]。Salamero[7]使用eBPF 實(shí)現(xiàn)了一個(gè)進(jìn)程異常行為檢測(cè)工具Falco,可通過連續(xù)監(jiān)視Linux 內(nèi)核中的系統(tǒng)調(diào)用來捕捉異常行為。但是Falco 主要基于預(yù)先設(shè)定的規(guī)則來判斷異常行為,不能有效防御未知漏洞的攻擊。Jian 等[8]提出基于容器內(nèi)進(jìn)程所屬命名空間(namespaces)[9]的變化來檢測(cè)容器逃逸行為。但該方案存在2 個(gè)缺陷:檢測(cè)滯后性和檢測(cè)失效性。

        為了解決現(xiàn)有容器逃逸檢測(cè)中漏報(bào)率較高的問題,本文提出了一種異構(gòu)觀測(cè)的實(shí)時(shí)檢測(cè)方法,并實(shí)現(xiàn)了基于異構(gòu)觀測(cè)鏈的容器逃逸檢測(cè)原型系統(tǒng),簡稱HOC-Detector。首先,通過大量復(fù)現(xiàn)利用內(nèi)核漏洞實(shí)現(xiàn)的容器逃逸攻擊案例,對(duì)容器逃逸流程進(jìn)行建模,將相應(yīng)的攻擊案例劃分為直接逃逸和間接逃逸。容器逃逸后獲得root 權(quán)限的逃逸進(jìn)程是容器內(nèi)進(jìn)程的子進(jìn)程則為直接逃逸;反之則為間接逃逸。然后,對(duì)已有利用內(nèi)核漏洞的容器逃逸行為進(jìn)行觀測(cè),并總結(jié)、提煉出一系列觀測(cè)點(diǎn),包括進(jìn)程的用戶ID(uid)、組ID(gid)、能力(capabilities)[10]、根目錄(root directory)以及namespaces 等。同時(shí)提出容器逃逸是由一系列以“權(quán)限提升”為目的的攻擊手段組合而成的。最后,基于捕獲的進(jìn)程行為生成容器進(jìn)程的起源圖,結(jié)合觀測(cè)點(diǎn)構(gòu)建容器進(jìn)程逃逸行為的異構(gòu)觀測(cè)鏈,以是否出現(xiàn)“權(quán)限提升”為檢測(cè)標(biāo)準(zhǔn),對(duì)容器進(jìn)程全生命周期進(jìn)行觀測(cè),實(shí)現(xiàn)對(duì)利用內(nèi)核漏洞實(shí)施容器逃逸的檢測(cè)。本文的主要貢獻(xiàn)總結(jié)如下。

        1) 首先調(diào)研并復(fù)現(xiàn)了10 個(gè)利用內(nèi)核漏洞(CVE-2016-5195、CVE-2017-7308、CVE-2017-11176、CVE-2017-18344、CVE-2017-1000112、CVE-2018-18955、CVE-2020-14386、CVE-2021-22555、CVE-2022-0185、CVE-2022-0847)的容器逃逸案例,對(duì)利用內(nèi)核漏洞的容器逃逸流程進(jìn)行建模,提煉出容器逃逸行為的主要觀測(cè)點(diǎn)和基于“權(quán)限提升”的容器逃逸檢測(cè)標(biāo)準(zhǔn)。

        2) 利用Linux 內(nèi)核模塊實(shí)現(xiàn)了對(duì)容器進(jìn)程操作行為的捕獲和進(jìn)程屬性信息的提取,進(jìn)一步生成了進(jìn)程起源圖。

        3) 提出異構(gòu)觀測(cè)的檢測(cè)方法,基于容器進(jìn)程起源圖和觀測(cè)點(diǎn)構(gòu)建異構(gòu)觀測(cè)鏈,從多個(gè)角度對(duì)容器進(jìn)程所執(zhí)行的操作進(jìn)行全生命周期的異構(gòu)觀測(cè),檢測(cè)是否有權(quán)限提升的情況。

        4) 為了驗(yàn)證系統(tǒng)的有效性,選取4 個(gè)具有代表性的容器逃逸內(nèi)核漏洞,并與容器逃逸檢測(cè)工具NS-Detector 進(jìn)行對(duì)比。其中,利用這4 個(gè)漏洞實(shí)現(xiàn)的容器逃逸涵蓋了本文總結(jié)出的兩類逃逸方式:直接逃逸和間接逃逸。實(shí)驗(yàn)結(jié)果表明,本文所提方法可以實(shí)時(shí)檢測(cè)直接和間接逃逸。同時(shí),基于真實(shí)場(chǎng)景的實(shí)驗(yàn)分析表明,本文的系統(tǒng)有較小的性能開銷。

        1 相關(guān)工作

        Linux 下的容器技術(shù)基于內(nèi)核中的namespaces[9]實(shí)現(xiàn)隔離控制,基于cgroups[11]實(shí)現(xiàn)資源分配。由于容器進(jìn)程與宿主機(jī)進(jìn)程共享系統(tǒng)內(nèi)核,攻擊者可以在容器內(nèi)利用內(nèi)核漏洞實(shí)現(xiàn)容器逃逸,進(jìn)而對(duì)整個(gè)物理機(jī)環(huán)境造成危害[6]。為了在逃逸后獲得root 權(quán)限的交互式命令解釋器(shell),攻擊者通常會(huì)先提升當(dāng)前進(jìn)程的權(quán)限,因此可以通過動(dòng)態(tài)實(shí)時(shí)監(jiān)控容器內(nèi)進(jìn)程是否有提權(quán)行為來防御逃逸。Lin 等[12]提出的利用內(nèi)核漏洞的提權(quán)一般包含4 個(gè)步驟:繞過內(nèi)核地址空間布局隨機(jī)化(KASLR,kernel address space layout randomization)[13]、繞過管理模式訪問保護(hù)(SMAP,supervisor mode access prevention)和管理模式執(zhí)行保護(hù)(SMEP,supervisor mode execution prevention)[14]、覆蓋內(nèi)核函數(shù)指針劫持控制流和調(diào)用內(nèi)核函數(shù)commit_creds()。Lin 等認(rèn)為前3 個(gè)步驟很難直接檢測(cè),所以提出通過檢測(cè)進(jìn)程是否調(diào)用函數(shù)commit_creds()來阻止容器內(nèi)進(jìn)程的提權(quán)行為。但是,在實(shí)踐中存在一些其他的內(nèi)核提權(quán)方法,并不會(huì)通過調(diào)用函數(shù)comm_cred()來進(jìn)行提權(quán)。比如,攻擊者可以利用Linux 內(nèi)核寫時(shí)復(fù)制(copy-on-write)中的條件競爭漏洞[15],繞過虛擬動(dòng)態(tài)共享對(duì)象(vDSO,virtual dynamic shared object)[16]對(duì)進(jìn)程內(nèi)存權(quán)限的限制,將漏洞利用代碼(shellcode)[17]注入vDSO 實(shí)現(xiàn)提權(quán)并逃逸。

        此外,Jian 等[8]提出了一種基于進(jìn)程所屬namespaces狀態(tài)變化的方案NS-Detecto(rnamespaces detector)來檢測(cè)Docker 容器的逃逸行為。Jian 等認(rèn)為,當(dāng)攻擊者從容器中逃逸至宿主機(jī)并獲得一個(gè)可控的shell 時(shí),該進(jìn)程仍屬于容器中進(jìn)程的子進(jìn)程,但其namespaces 已突破容器與宿主機(jī)間的隔離,屬于宿主機(jī)進(jìn)程的namespaces。該方案主要存在2 個(gè)缺陷:一是檢測(cè)滯后性,因?yàn)槿萜魈右萃ǔT谧詈笠徊讲艜?huì)突破namespaces 的隔離;二是檢測(cè)失效性,攻擊者在容器內(nèi)利用內(nèi)核漏洞提權(quán)并獲得對(duì)宿主機(jī)目錄操作權(quán)限后,可以通過服務(wù)cron 創(chuàng)建定時(shí)任務(wù)的方式來獲取一個(gè)反彈shell[18],實(shí)現(xiàn)“間接”容器逃逸。此時(shí),獲得的可控shell 與容器中進(jìn)程無直接關(guān)系,該方案不能檢測(cè)出此類型的容器逃逸。

        另一類常見的檢測(cè)容器逃逸的方法是安全容器[19-20]。與普通容器相比,安全容器運(yùn)行在一個(gè)獨(dú)立的微型虛擬機(jī)中,擁有完整的操作系統(tǒng)內(nèi)核。安全容器是通過隔離層增強(qiáng)容器的安全性,即在容器和內(nèi)核之間增加隔離層來阻止逃逸。典型的安全容器技術(shù)有Kata[19]和gVisor[20]。安全容器雖然實(shí)現(xiàn)了容器和內(nèi)核的安全隔離,但中間隔離層的引入增加了攻擊面,可能會(huì)導(dǎo)致其他未知的風(fēng)險(xiǎn)。

        首先,本文討論的容器逃逸檢測(cè)技術(shù)主要針對(duì)普通容器。其次,Lin 等的工作用于檢測(cè)內(nèi)核提權(quán),Jian 等提出的NS-Detector 是目前唯一用于檢測(cè)利用內(nèi)核漏洞實(shí)現(xiàn)容器逃逸的工作,與本文研究內(nèi)容直接相關(guān)。總體來說,當(dāng)前對(duì)利用內(nèi)核漏洞實(shí)現(xiàn)容器逃逸行為的檢測(cè)方案主要面臨檢測(cè)漏報(bào)率較高的問題。在2.3 節(jié)中,本文對(duì)利用內(nèi)核實(shí)現(xiàn)的容器逃逸建模后將逃逸行為劃分為直接逃逸和間接逃逸。當(dāng)前的容器逃逸檢測(cè)方案僅能檢測(cè)直接逃逸,無法有效檢測(cè)間接逃逸。本文提出異構(gòu)觀測(cè)鏈的方法可以在保證檢測(cè)直接逃逸的前提下檢測(cè)間接逃逸。

        2 預(yù)備知識(shí)

        2.1 開放起源模型OPM

        2008 年,Moreau 等[21]提出了開放起源模型(OPM,open provenance model)。OPM 的本質(zhì)是一個(gè)包含不同對(duì)象間依賴關(guān)系的有向無環(huán)圖,可用于描述某一對(duì)象在特定時(shí)間階段的所有操作。OPM 示例如圖1 所示,共定義了3 類節(jié)點(diǎn)。

        圖1 OPM 示例

        1) 狀態(tài)(artifact):用橢圓形表示,代表不可變的狀態(tài),對(duì)應(yīng)于計(jì)算機(jī)中的數(shù)據(jù)對(duì)象。

        2) 過程(process):用矩形表示,代表施加在數(shù)據(jù)對(duì)象上的行為,可以產(chǎn)生新的狀態(tài)節(jié)點(diǎn)。

        3) 代理(agent):用六邊形表示,用于控制或影響過程的執(zhí)行。

        3 類節(jié)點(diǎn)之間的邊代表不同的因果(依賴)關(guān)系:有向邊的頭部是結(jié)果,尾部(箭頭)是原因。如圖1 所示,3 類節(jié)點(diǎn)之間有5 種依賴關(guān)系。

        1) used:該依賴關(guān)系代表過程P 的執(zhí)行需要使用狀態(tài)A。

        2) wasGeneratedBy:該依賴關(guān)系代表過程P 的執(zhí)行產(chǎn)生了狀態(tài)A。

        3) wasTriggeredBy:該依賴關(guān)系代表過程P2的執(zhí)行需要過程P1先執(zhí)行。一般P1是父進(jìn)程,P2是子進(jìn)程。

        4) wasControlledBy:該依賴關(guān)系代表過程P 的開始和結(jié)束都由代理Ag 控制。

        5) wasDerivedFrom:該依賴關(guān)系代表狀態(tài)A2描述的數(shù)據(jù)對(duì)象依賴于狀態(tài)A1所代表的數(shù)據(jù)對(duì)象。

        在OPM 中,一個(gè)過程可能使用或產(chǎn)生多個(gè)狀態(tài),也有可能被多個(gè)代理控制,所以需要準(zhǔn)確地識(shí)別這些狀態(tài)集和代理集。OPM 引入角色的概念,如圖1 所示,每條邊上標(biāo)注了角色(R),并且給每個(gè)狀態(tài)和代理規(guī)定唯一標(biāo)識(shí)的角色。

        2.2 逃逸相關(guān)內(nèi)核數(shù)據(jù)結(jié)構(gòu)

        在Linux 系統(tǒng)中,根據(jù)特權(quán)級(jí)別不同,將進(jìn)程運(yùn)行狀態(tài)劃分為用戶態(tài)和內(nèi)核態(tài)。應(yīng)用程序一般運(yùn)行在用戶態(tài),當(dāng)其執(zhí)行系統(tǒng)調(diào)用或發(fā)生中斷而陷入內(nèi)核中執(zhí)行時(shí),就稱進(jìn)程處于內(nèi)核態(tài)。當(dāng)進(jìn)程在內(nèi)核態(tài)時(shí),可以直接訪問操作系統(tǒng)內(nèi)核中與進(jìn)程屬性相關(guān)的數(shù)據(jù)結(jié)構(gòu)。因此,攻擊者可以利用內(nèi)核漏洞劫持控制流來執(zhí)行惡意代碼修改容器進(jìn)程與權(quán)限相關(guān)的數(shù)據(jù)結(jié)構(gòu),從而提升容器進(jìn)程的權(quán)限,進(jìn)一步實(shí)現(xiàn)逃逸。內(nèi)核中與容器逃逸相關(guān)的重要數(shù)據(jù)結(jié)構(gòu)如圖2 所示。

        圖2 內(nèi)核中與容器逃逸相關(guān)的重要數(shù)據(jù)結(jié)構(gòu)

        1) task_struct:內(nèi)核中與進(jìn)程管理和控制相關(guān)最重要的數(shù)據(jù)結(jié)構(gòu)。該結(jié)構(gòu)體伴隨進(jìn)程整個(gè)生命周期,記錄進(jìn)程的當(dāng)前狀態(tài)以及控制進(jìn)程運(yùn)行的全部信息(打開的文件、信號(hào)量、進(jìn)程狀態(tài)、地址空間等)。

        2) cred:系統(tǒng)通過該結(jié)構(gòu)體控制進(jìn)程對(duì)其他資源的操作權(quán)限判定。當(dāng)進(jìn)程操作消息隊(duì)列、共享內(nèi)存和信息量等數(shù)據(jù)對(duì)象時(shí),系統(tǒng)需要對(duì)進(jìn)程的euid、egid 進(jìn)行檢查;當(dāng)進(jìn)程執(zhí)行文件相關(guān)的操作時(shí),系統(tǒng)需要對(duì)進(jìn)程的fsuid、fsgid 進(jìn)行檢查。同時(shí),Linux使用能力(capability)機(jī)制,以細(xì)粒度方式控制普通進(jìn)程能否執(zhí)行“特權(quán)”操作。例如,進(jìn)程要掛載(mount)一個(gè)文件系統(tǒng),那么進(jìn)程需要有對(duì)應(yīng)的capability,即CAP_SYS_ADMIN。

        3) fs_struct:用于描述進(jìn)程的文件系統(tǒng)信息。結(jié)構(gòu)體中的root 和pwd 分別代表進(jìn)程的根目錄和當(dāng)前工作目錄。

        4) nsproxy:用于描述進(jìn)程各個(gè)namespaces 的狀態(tài)。其中,pid namespaces 為進(jìn)程提供了一個(gè)具有獨(dú)立進(jìn)程ID 的運(yùn)行環(huán)境。在每一個(gè)pid namespaces 中,進(jìn)程的pid 從1 開始編號(hào),且和其他pid namespaces 中的pid 互不影響。

        2.3 容器逃逸模型

        利用內(nèi)核漏洞實(shí)現(xiàn)容器逃逸一般可分為兩步,攻擊者首先利用內(nèi)核漏洞劫持內(nèi)核的控制流,然后執(zhí)行惡意代碼實(shí)現(xiàn)容器逃逸。在復(fù)現(xiàn)并觀測(cè)大量利用內(nèi)核漏洞的容器逃逸后,本文將逃逸行為建模為如圖3 所示的流程。根據(jù)逃逸后獲取的root 權(quán)限進(jìn)程(shell)是否為容器中進(jìn)程的子進(jìn)程,將容器逃逸分為兩類:直接逃逸和間接逃逸。

        圖3 利用內(nèi)核漏洞的直接、間接逃逸流程

        2.3.1 直接逃逸

        在直接逃逸中,攻擊者在劫持內(nèi)核控制流之后一般會(huì)提升當(dāng)前容器進(jìn)程的權(quán)限,確保逃逸后可以獲得root 權(quán)限的進(jìn)程。如圖3 所示,攻擊者首先觸發(fā)內(nèi)核漏洞,通過覆蓋內(nèi)核函數(shù)指針,將內(nèi)核控制流劫持到用戶態(tài)。在 Payload 中調(diào)用內(nèi)核函數(shù)commit_creds(prepare_kernel_cred(0)) 將當(dāng)前進(jìn)程(cur)的cred 替換為root 權(quán)限的cred。然后,執(zhí)行內(nèi)核函數(shù)switch_task_namespacess(cur,INIT_NSPROXY) 突破系統(tǒng)對(duì)容器內(nèi)進(jìn)程的Namespaces 隔離。最后,cur 進(jìn)程創(chuàng)建一個(gè)root 權(quán)限的逃逸進(jìn)程,實(shí)現(xiàn)直接容器逃逸。

        2.3.2 間接逃逸

        間接逃逸與直接逃逸最大的區(qū)別是不需要容器內(nèi)的進(jìn)程突破namespaces 的隔離也能獲得root權(quán)限的逃逸進(jìn)程。如圖3 中的3.1) 所示,攻擊者劫持控制流后,在 Payload 中依次執(zhí)行內(nèi)核函數(shù)commit_creds(prepare_kernel_cred(0))和copy_fs_struct(init+TASK_FS_OFFSET),分別提升容器內(nèi)當(dāng)前進(jìn)程的權(quán)限和將進(jìn)程根目錄切換為宿主機(jī)上1 號(hào)進(jìn)程的根目錄。此時(shí),攻擊者可以通過改寫宿主機(jī)文件的方式實(shí)現(xiàn)逃逸。例如,容器中的進(jìn)程在宿主機(jī)/var/spool/cron/crontabs/目錄下新建root 文件,向其中寫入執(zhí)行反彈shell 的命令,當(dāng)宿主機(jī)的root 權(quán)限的進(jìn)程cron 執(zhí)行該文件中的命令后獲得一個(gè)root權(quán)限的交互式shell。最后得到的root 權(quán)限進(jìn)程與容器中的進(jìn)程并無直接繼承關(guān)系,實(shí)現(xiàn)間接容器逃逸。另一種實(shí)現(xiàn)間接逃逸的方式是在劫持內(nèi)核控制流后不調(diào)用內(nèi)核函數(shù),而是用shellcode 覆蓋內(nèi)核中的函數(shù)。如圖3 中的3.2) 所示,攻擊者覆蓋內(nèi)核中的clock_gettime()函數(shù),隨后宿主機(jī)上root 權(quán)限的進(jìn)程調(diào)用clock_gettime()函數(shù)獲取時(shí)間時(shí)會(huì)開啟一個(gè)root 權(quán)限的shell,實(shí)現(xiàn)間接逃逸。

        因此,利用內(nèi)核漏洞實(shí)現(xiàn)的容器逃逸在其逃逸過程中所執(zhí)行的操作一般會(huì)表現(xiàn)出“權(quán)限提升”的特點(diǎn)。從攻防雙方來看,攻擊者可以憑此探索新的容器逃逸方法,一旦有新的內(nèi)核漏洞,就可以考慮是否可用于容器逃逸;防守者則可以針對(duì)此特征來檢測(cè)容器進(jìn)程生命周期中有無權(quán)限提升發(fā)生,以此來防御利用內(nèi)核漏洞實(shí)現(xiàn)的容器逃逸。

        進(jìn)程執(zhí)行不同操作前后的屬性變化能體現(xiàn)出權(quán)限提升,而進(jìn)程屬性本質(zhì)上由內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)來控制。因此,為了觀測(cè)進(jìn)程生命周期中是否存在權(quán)限提升,本文基于內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)選取觀測(cè)點(diǎn)列表S為[fs_root,cap_permited,uid,gid,mnt_ns,pid_ns,net_ns],其中,fs_root 表示進(jìn)程的根目錄,cap_permited 表示進(jìn)程所能夠擁有特權(quán)的上限,uid和gid 分別表示進(jìn)程所屬的用戶ID 和組ID,觀測(cè)點(diǎn)列表中剩余部分均與進(jìn)程的namespaces 相關(guān)。

        為檢測(cè)上述2 類容器逃逸,本文基于進(jìn)程的操作構(gòu)建進(jìn)程起源圖,以此來描述進(jìn)程行為之間的關(guān)系。隨后,結(jié)合進(jìn)程起源圖和觀測(cè)點(diǎn)構(gòu)建異構(gòu)觀測(cè)鏈,對(duì)進(jìn)程完整生命周期進(jìn)行監(jiān)控,即檢測(cè)進(jìn)程行為引發(fā)的觀測(cè)點(diǎn)屬性變化情況,若存在權(quán)限提升的屬性變化,則判定進(jìn)程正在進(jìn)行逃逸。

        3 系統(tǒng)實(shí)現(xiàn)

        本文所提出的基于異構(gòu)觀測(cè)鏈的容器進(jìn)程實(shí)時(shí)檢測(cè)系統(tǒng)旨在通過對(duì)容器內(nèi)的進(jìn)程進(jìn)行全生命周期的監(jiān)控來檢測(cè)是否存在利用內(nèi)核漏洞的容器逃逸行為。為此,一方面需要確保監(jiān)控和檢測(cè)過程的實(shí)時(shí)性,在不能引入過高的性能開銷的同時(shí)也需要保證系統(tǒng)的穩(wěn)定運(yùn)行;另一方面需要保證檢測(cè)的有效性。因此,系統(tǒng)的設(shè)計(jì)目標(biāo)包括以下4 個(gè)方面。

        1) 保證捕捉進(jìn)程行為和提取進(jìn)程屬性信息的實(shí)時(shí)性?;诖艘?,HOC-Detector 需要及時(shí)捕獲進(jìn)程的操作,然后提取其行為、屬性信息。

        2) 盡量減小逃逸檢測(cè)時(shí)延。為減小檢測(cè)逃逸的時(shí)延,除需要快速提取進(jìn)程的行為、屬性信息外,還需要縮小逃逸檢測(cè)的范圍。

        3) 引入較小的性能開銷。在確保進(jìn)程信息提取的實(shí)時(shí)性、檢測(cè)低時(shí)延的前提下,盡量減小HOC-Detector 對(duì)系統(tǒng)造成運(yùn)行時(shí)開銷。

        4) 能夠防御未知威脅。對(duì)于使用未知內(nèi)核漏洞進(jìn)行容器逃逸的行為,HOC-Detector 要能準(zhǔn)確地捕捉,以確保逃逸檢測(cè)的有效性。

        3.1 異構(gòu)觀測(cè)鏈概述

        進(jìn)程的動(dòng)態(tài)行為可由其所執(zhí)行的一系列操作來刻畫。當(dāng)進(jìn)程進(jìn)行容器逃逸時(shí),往往會(huì)執(zhí)行一些特別的操作來繞過系統(tǒng)中的安全機(jī)制,而操作前后進(jìn)程的屬性變化可以反映出這些操作是否合法。為此,本文借助OPM 將系統(tǒng)中進(jìn)程執(zhí)行的所有操作抽象為進(jìn)程起源圖,從起源圖上提取容器內(nèi)進(jìn)程的觀測(cè)鏈。如圖4 所示,該觀測(cè)鏈由進(jìn)程、文件等對(duì)象以及表征其相關(guān)操作的有向依賴邊構(gòu)成。

        圖4 基于進(jìn)程行為起源圖的異構(gòu)觀測(cè)鏈

        本文將觀測(cè)鏈中依賴邊的尾部(箭頭)節(jié)點(diǎn)稱為主體,用T(tail)表示;邊的頭部節(jié)點(diǎn)稱為客體,用H(head)表示;主體和客體均可以是進(jìn)程、文件等。進(jìn)程用Ppid表示,其中pid 為進(jìn)程號(hào);文件等其他資源用Aname表示,其中name 為標(biāo)識(shí)符。主體與客體間的行為用Oop表示,其中op∈{fork,clone,read,write,…};主體對(duì)客體之間的操作關(guān)系用TOopH 表示。

        如圖4 所示,節(jié)點(diǎn)代表containerd-shim 進(jìn)程,在T2時(shí)刻,容器中的init 進(jìn)程 P1021復(fù)制了一個(gè)子進(jìn)程 P1022,該操作可以表示為 P1021OforkP1022。在T3時(shí)刻,P1022運(yùn)行漏洞利用程序后創(chuàng)建了一個(gè)新的進(jìn)程P1023,該操作可以表示為 P1022OforkP1023。在T4時(shí)刻,該進(jìn)程讀取了宿主機(jī)中/etc/shadow 文件中的內(nèi)容P1023OreadAshadow。從圖 4 中得到的觀測(cè)鏈為(P1021OforkP1022) ∧(P1022OforkP1023) ∧(P1023OreadAshadow)。其中,符號(hào)∧用來連接觀測(cè)鏈上進(jìn)程的操作。

        在得到容器內(nèi)進(jìn)程的觀測(cè)鏈后,本文基于2.3 節(jié)中提出的觀測(cè)點(diǎn)列表S,在進(jìn)程生命周期中不同的時(shí)間節(jié)點(diǎn)對(duì)進(jìn)程的操作進(jìn)行異構(gòu)觀測(cè)。采用3.5 節(jié)中提出的檢測(cè)標(biāo)準(zhǔn)來評(píng)估進(jìn)程操作是否存在權(quán)限提升,以此來判斷是否發(fā)生了逃逸行為。使用異構(gòu)觀測(cè)鏈的方法來檢測(cè)容器逃逸有2 個(gè)明顯的優(yōu)勢(shì),一是異構(gòu)觀測(cè)鏈涵蓋進(jìn)程在不同時(shí)間點(diǎn)所執(zhí)行的操作,可以在早期就檢測(cè)到進(jìn)程的逃逸行為,顯著降低逃逸檢測(cè)的時(shí)延;二是異構(gòu)觀測(cè)鏈包含進(jìn)程生命周期中所有相關(guān)的操作,可以對(duì)進(jìn)程實(shí)現(xiàn)全面的監(jiān)控,顯著降低逃逸檢測(cè)的漏報(bào)。

        3.2 總體架構(gòu)

        HOC-Detector 總體架構(gòu)如圖5 所示,由進(jìn)程日志獲取模塊(AuditLogger)、進(jìn)程起源圖生成模塊(PPGGenerator )、異構(gòu)觀測(cè)鏈構(gòu)建模塊(HOCBuilder)、攻擊檢測(cè)模塊(AttackDetector)和預(yù)先配置的觀測(cè)點(diǎn)(ObservationPoints)五部分組成。在HOC-Detector 運(yùn)行過程中,AuditLogger 在系統(tǒng)內(nèi)核中監(jiān)視進(jìn)程,并將其行為、屬性信息保存在宿主機(jī)的日志文件中;與此同時(shí),PPGGenerator 從日志文件中讀取內(nèi)容,采取基于因果關(guān)系的方法構(gòu)建進(jìn)程的起源圖,并將其傳遞給 HOCBuilder;HOCBuilder 基于起源圖并結(jié)合用戶提供的觀測(cè)點(diǎn)構(gòu)建異構(gòu)觀測(cè)鏈,AttackDetector 對(duì)異構(gòu)觀測(cè)鏈進(jìn)行分析,檢測(cè)容器進(jìn)程是否存在逃逸行為。

        為了對(duì)基于內(nèi)核的容器逃逸有更清晰的了解,本文在2.3 節(jié)中通過對(duì)內(nèi)核漏洞導(dǎo)致的容器逃逸進(jìn)行大量復(fù)現(xiàn)后,對(duì)其逃逸流程進(jìn)行建模。同時(shí),從是否能很好地表征權(quán)限提升的角度選取進(jìn)程的屬性信息作為觀測(cè)點(diǎn)。如圖5 中的ObservationPoints所示,觀測(cè)點(diǎn)列表為[S[1],S[2],…,S[m]]。同時(shí),為了增加對(duì)未知威脅的防御能力,可以動(dòng)態(tài)調(diào)整HOC-Detector 中的觀測(cè)點(diǎn)。

        圖5 HOC-Dectector 總體架構(gòu)

        在HOC-Detector 的運(yùn)行過程中,AuditLogger需要持續(xù)實(shí)時(shí)地捕捉進(jìn)程的行為和記錄屬性的信息。因此,本文使用內(nèi)核編程的方式通過動(dòng)態(tài)可加載的內(nèi)核模塊在內(nèi)核中截取進(jìn)程所執(zhí)行的系統(tǒng)調(diào)用,記錄其系統(tǒng)調(diào)用名、參數(shù)和返回值等信息,實(shí)現(xiàn)對(duì)進(jìn)程行為的實(shí)時(shí)監(jiān)控。HOC-Detector 的設(shè)計(jì)目標(biāo)是檢測(cè)利用內(nèi)核漏洞的容器逃逸,而容器本質(zhì)上是宿主機(jī)上使用namespaces 和cgroups 實(shí)現(xiàn)資源隔離的普通進(jìn)程。宿主機(jī)上的進(jìn)程數(shù)目龐大,為了實(shí)現(xiàn)容器逃逸檢測(cè)的實(shí)時(shí)性,本文需要重點(diǎn)關(guān)注容器相關(guān)的進(jìn)程。因此,需要識(shí)別出容器內(nèi)外進(jìn)程的邊界,減輕后續(xù)異構(gòu)觀測(cè)鏈構(gòu)建和攻擊檢測(cè)的復(fù)雜度。PPGGenerator 對(duì)記錄的進(jìn)程日志信息進(jìn)行語義解析,構(gòu)建進(jìn)程起源圖。隨后,HOCBuilder 結(jié)合起源圖和觀測(cè)點(diǎn)構(gòu)建異構(gòu)觀測(cè)鏈。最后,AttackDetector 基于異構(gòu)觀測(cè)鏈檢測(cè)進(jìn)程的整個(gè)生命周期中是否存在權(quán)限提升的情況,判斷是否存在容器逃逸行為。如圖5 中的AttackDetector 所示,該模塊對(duì)進(jìn)程操作前后的每個(gè)觀測(cè)點(diǎn)Si進(jìn)行對(duì)比,判斷其是否存在權(quán)限提升,ai表示檢測(cè)結(jié)果。當(dāng)超過半數(shù)的觀測(cè)點(diǎn)存在權(quán)限提升時(shí),本文判定當(dāng)前進(jìn)程存在逃逸行為。

        3.3 基于內(nèi)核模塊的進(jìn)程信息提取

        Linux 系統(tǒng)中的/proc 目錄是一種虛擬文件系統(tǒng),該目錄下的文件描述了內(nèi)核當(dāng)前的運(yùn)行狀態(tài),可以在用戶態(tài)通過讀取/proc/pid 目錄下文件的內(nèi)容來查看當(dāng)前正在運(yùn)行進(jìn)程的信息。該方法主要面臨2 個(gè)挑戰(zhàn):一是系統(tǒng)中的進(jìn)程數(shù)目龐大,頻繁讀取/proc 目錄下文件中的內(nèi)容開銷很大;二是攻擊者在實(shí)施攻擊的過程中可能會(huì)隱藏一些進(jìn)程,導(dǎo)致不能在/proc 目錄下找到對(duì)應(yīng)進(jìn)程的信息。因此,本文通過內(nèi)核模塊編程的方式在內(nèi)核態(tài)提取與進(jìn)程相關(guān)的關(guān)鍵屬性信息,并將其保存到宿主機(jī)的日志文件中。

        本文所選取的觀測(cè)點(diǎn)可以通過進(jìn)程描述符task_struct 獲取,所以首先需要得到進(jìn)程的task_struct結(jié)構(gòu)體,然后根據(jù)其結(jié)構(gòu)體成員提取進(jìn)程觀測(cè)點(diǎn)信息。該功能由HOC-Detector 中的AuditLogger 模塊實(shí)現(xiàn),采用Linux Audit[22]技術(shù)在內(nèi)核中捕捉系統(tǒng)中所有進(jìn)程的各種操作行為,如系統(tǒng)調(diào)用、文件讀寫、執(zhí)行命令等。其具體實(shí)現(xiàn)流程如下。

        1) 在內(nèi)核態(tài)截取與新進(jìn)程創(chuàng)建相關(guān)的系統(tǒng)調(diào)用,例如clone、fork 和vfork。當(dāng)進(jìn)程執(zhí)行這些系統(tǒng)調(diào)用后,將其返回值傳給/include/linux/pid.h 中的函數(shù)find_vpid()以獲取新進(jìn)程的struct pid 結(jié)構(gòu)體指針,它指向的結(jié)構(gòu)體保存了新進(jìn)程的進(jìn)程描述符信息。

        2) 把步驟1)中指向struct pid 的指針作為函數(shù)pid_task()的參數(shù),得到進(jìn)程的task_struct 結(jié)構(gòu)體。

        3) 利用__task_cred()讀取task_struct 中的指針cred 所指向的結(jié)構(gòu)體,從中提取進(jìn)程的用戶和組權(quán)限uid、gid、euid、fsuid 等。同時(shí),提取進(jìn)程的細(xì)粒度權(quán)限信息cap_permitted。

        4) 通過task_struct中的指針fs指向的結(jié)構(gòu)體獲得進(jìn)程根目錄root,然后根據(jù)root 中的dentry 得到根目錄項(xiàng)中表示所有子目錄的鏈表指針d_subdirs。最后,通過遍歷d_subdirs 得到根目錄下所有子目錄或子文件的名字。

        5) 通過task_struct 中的指針nsproxy 指向的結(jié)構(gòu)體獲得進(jìn)程namespaces 的信息。

        6) 系統(tǒng)中的每個(gè)進(jìn)程可能屬于多個(gè)不同的namespaces,通過結(jié)構(gòu)體struct pid 中的numbers 數(shù)組來獲取進(jìn)程在不同pid namespaces 中的進(jìn)程編號(hào)。在容器逃逸場(chǎng)景下,pid 表示進(jìn)程在宿主機(jī)環(huán)境下的進(jìn)程號(hào)(全局進(jìn)程號(hào)),vpid 表示容器中進(jìn)程在其隔離的pid namespaces 中的進(jìn)程號(hào)(局部進(jìn)程號(hào))。

        如圖6 所示,runc 進(jìn)程(父進(jìn)程,pid=2556)正在執(zhí)行容器初始化,它通過執(zhí)行系統(tǒng)調(diào)用號(hào)為56的clone 來創(chuàng)建一個(gè)子進(jìn)程(pid=2557)。本文將進(jìn)程編號(hào)2557 作為參數(shù)依次執(zhí)行上面描述的操作來提取新進(jìn)程的信息。為了方便對(duì)比在新進(jìn)程創(chuàng)建時(shí)有無權(quán)限提升的情況發(fā)生,本文也會(huì)提取父進(jìn)程的相關(guān)屬性信息。如圖6 所示,子進(jìn)程的命名空間與父進(jìn)程的命名空間(mnt_ns,pid_ns,net_ns)不一致,并且子進(jìn)程的局部進(jìn)程編號(hào)為1(vpid=1),說明該子進(jìn)程是新啟動(dòng)的容器中的init 進(jìn)程。為了方便表示進(jìn)程的根目錄,本文將容器內(nèi)的進(jìn)程根目錄root_path 標(biāo)識(shí)為container,容器外進(jìn)程標(biāo)識(shí)為host。

        圖6 內(nèi)核模塊提取的進(jìn)程觀測(cè)點(diǎn)信息

        3.4 容器內(nèi)外進(jìn)程邊界識(shí)別

        宿主機(jī)操作系統(tǒng)使用Linux 中的Namespaces技術(shù)來限制容器進(jìn)程可見的資源,使運(yùn)行在同一宿主機(jī)下不同容器中的程序之間互不影響。使用cgroups 技術(shù)來限制進(jìn)程可使用的資源,確保宿主機(jī)上所有容器公平使用宿主機(jī)上的資源,如CPU、內(nèi)存、磁盤和網(wǎng)絡(luò)等。所以,容器僅是宿主機(jī)上的一個(gè)特殊的進(jìn)程,與其他進(jìn)程相比沒有本質(zhì)的區(qū)別。但Linux Audit 在記錄進(jìn)程信息時(shí)并不會(huì)區(qū)分當(dāng)前進(jìn)程是普通進(jìn)程還是容器進(jìn)程,而容器內(nèi)進(jìn)程的行為是本文檢測(cè)容器逃逸的關(guān)鍵。為了優(yōu)化異構(gòu)觀測(cè)鏈的構(gòu)建以及提高容器逃逸的檢測(cè)效率,本文提出建立對(duì)容器內(nèi)外進(jìn)程邊界的識(shí)別,該過程僅需關(guān)注與容器內(nèi)進(jìn)程及其行為相關(guān)的進(jìn)程。

        通過分析Docker 容器的初始化流程可以發(fā)現(xiàn),容器的啟動(dòng)有固定的模式,基于此來識(shí)別容器內(nèi)外進(jìn)程的邊界。容器的初始化以執(zhí)行系統(tǒng)調(diào)用unshare創(chuàng)建新的命名空間系統(tǒng)開始,以執(zhí)行系統(tǒng)調(diào)用execve 在容器內(nèi)創(chuàng)建新的init 進(jìn)程結(jié)束。本文以Docker 容器的初始化為例,如圖7 所示,其初始化流程介紹如下。

        圖7 Docker 容器初始化流程

        1) dockerd 通過gPRC 接口向容器運(yùn)行時(shí)管理引擎containerd 發(fā)送指令創(chuàng)建容器,隨后containerd(pid=1405)會(huì)啟動(dòng)一個(gè)進(jìn)程 containerd-shim(pid=2522),由它負(fù)責(zé)創(chuàng)建一個(gè)新的容器。

        2) 該進(jìn)程(pid=2522)會(huì)復(fù)制出一系列的containerd-shim 進(jìn)程,其中一個(gè) containerd-shim(pid=2532)會(huì)創(chuàng)建新的runC 進(jìn)程來完成容器初始化操作。

        3) 進(jìn)程 runc(pid=2540)會(huì)復(fù)制出子進(jìn)程runc:[0:PARENT],該進(jìn)程的子進(jìn)程runc:[1:CHILD]會(huì)執(zhí)行系統(tǒng)調(diào)用unshare 創(chuàng)建新的命名空間,標(biāo)志著開始進(jìn)行實(shí)際的容器初始化。

        4) 進(jìn)程 runc:[1:CHILD]會(huì)復(fù)制一些子進(jìn)程runc:[2:INIT]來完成一些特定的初始化任務(wù),包括設(shè)置/proc 和/rootfs 等。

        5) 最后,進(jìn)程runc:[1:CHILD]將復(fù)制一個(gè)子進(jìn)程(pid=2563),該子進(jìn)程即容器內(nèi)的init 進(jìn)程,它將執(zhí)行系統(tǒng)調(diào)用execve 來運(yùn)行容器默認(rèn)的啟動(dòng)程序(如bash)。

        HOC-Dectector 中的PPGGenerator 模塊基于系統(tǒng)收集的進(jìn)程行為信息構(gòu)建進(jìn)程起源圖,本文使用上述容器初始化模式在起源圖上標(biāo)記容器內(nèi)外進(jìn)程的邊界,僅關(guān)注容器內(nèi)的進(jìn)程,減輕后續(xù)構(gòu)建觀測(cè)鏈的工作量。

        3.5 異構(gòu)觀測(cè)鏈的構(gòu)建和逃逸行為的檢測(cè)

        觀測(cè)鏈的構(gòu)建依賴于能夠?qū)⑦M(jìn)程生命周期內(nèi)所有行為之間的依賴關(guān)系抽象為有向的進(jìn)程起源圖。HOC-Detector 中的HOCBuilder 模塊利用開源框架SPADE[23]來提取進(jìn)程起源圖,利用3.4 節(jié)中描述的方法識(shí)別容器內(nèi)外進(jìn)程的邊界和負(fù)責(zé)啟動(dòng)容器的containerd-shim 進(jìn)程。然后,以啟動(dòng)容器的containerd-shim 進(jìn)程為根節(jié)點(diǎn),以廣度優(yōu)先的方式遍歷起源圖,直到覆蓋所有子節(jié)點(diǎn)或者達(dá)到最大深度,最終從完整的起源圖中提取出與容器進(jìn)程相關(guān)的子圖。如圖4 所示,本文將從containerd-shim 進(jìn)程的節(jié)點(diǎn)到葉節(jié)點(diǎn)的一個(gè)節(jié)點(diǎn)序列稱為觀測(cè)鏈。

        如2.3 節(jié)所述,本文選取的觀測(cè)點(diǎn)列表為S。本文在AttackDetector 中將主體T 和客體H 之間單個(gè)觀測(cè)點(diǎn)的檢測(cè)標(biāo)準(zhǔn)Δ定義為

        其中,m為本文選取的觀測(cè)點(diǎn)列表S的長度,如2.3 節(jié)所述,m=7。冗余技術(shù)在軟件系統(tǒng)中可以極大提升系統(tǒng)的容錯(cuò)能力,從而提高系統(tǒng)的穩(wěn)定性。本文使用具有冗余能力的多數(shù)表決算法[24]來判定當(dāng)前操作是否存在權(quán)限提升。其基本思想是如果有超過半數(shù)觀測(cè)點(diǎn)的檢測(cè)標(biāo)準(zhǔn)Δ值為1,則判定為當(dāng)前主客體間的操作存在權(quán)限提升的行為,即如果(當(dāng)m=7時(shí),F(xiàn)AC≥ 4)則判定當(dāng)前的主客體間的操作存在權(quán)限提升,否則為正常操作。進(jìn)程的觀測(cè)鏈由多條邊組成,只要有一條邊(主客體間的操作)存在權(quán)限提升,本文就認(rèn)為該進(jìn)程發(fā)生容器逃逸。

        4 仿真分析

        4.1 實(shí)驗(yàn)設(shè)置

        為了驗(yàn)證HOC-Dectector 在防御利用內(nèi)核漏洞的容器逃逸攻擊時(shí)的有效性,本文選取了4 個(gè)影響較大的、可通過不同方式實(shí)現(xiàn)容器逃逸的CVE 內(nèi)核漏洞。本文的實(shí)驗(yàn)環(huán)境主要由物理機(jī)和容器引擎Docker 組成,物理機(jī)的配置為Intel(R) Core(TM)i7-9750H,4 核處理器,10 GB 內(nèi)存,200 GB 硬盤,具體的CVE 信息和系統(tǒng)實(shí)驗(yàn)環(huán)境如表1 所示。本文選擇的CVE包括CVE-2017-7308、CVE-2017-18344、CVE-2017-1000112 和CVE-2016-5195。第一個(gè)CVE 可通過調(diào)用內(nèi)核函數(shù)的方式實(shí)現(xiàn)直接容器逃逸;第二個(gè)和第三個(gè)CVE 一起使用,可通過調(diào)用內(nèi)核函數(shù)實(shí)現(xiàn)間接容器逃逸;最后一個(gè)CVE 可通過不調(diào)用內(nèi)核函數(shù)的方式實(shí)現(xiàn)間接容器逃逸。

        為檢驗(yàn)HOC-Detector 的有效性,本文復(fù)現(xiàn)了Jian 等提出的方法 NS-Detector 并與之對(duì)比。NS-Detector 通過監(jiān)測(cè)進(jìn)程所屬namespaces 的狀態(tài)變化來檢測(cè)針對(duì)Docker 容器的逃逸攻擊。其主要思想是攻擊者實(shí)現(xiàn)容器逃逸攻擊后獲得的root 權(quán)限逃逸進(jìn)程仍屬于容器內(nèi)進(jìn)程的子進(jìn)程,但其所屬Namespaces 已脫離容器的限制。本文將NS-Detector和HOC-Detector 在前述3 個(gè)容器逃逸的CVE 實(shí)驗(yàn)中進(jìn)行對(duì)比,實(shí)驗(yàn)結(jié)果如表 1 所示。其中,HOC-Detector 能檢測(cè)出所有的容器逃逸,準(zhǔn)確率達(dá)到100%,而NS-Detector 的準(zhǔn)確率約為33%。

        表1 容器逃逸檢測(cè)的內(nèi)核漏洞信息及實(shí)驗(yàn)環(huán)境和結(jié)果

        4.2 CVE-2017-7308

        AF_PACKET 是在Linux 平臺(tái)下的一種套接字(socket),用于在設(shè)備驅(qū)動(dòng)層發(fā)送或者接收數(shù)據(jù)包。進(jìn)程可以使用send 和recv 這2 個(gè)系統(tǒng)調(diào)用在數(shù)據(jù)包套接字上發(fā)送和接收數(shù)據(jù)包。為了提升效率,套接字提供了一個(gè)環(huán)形緩沖區(qū)(ring buffer),能夠使數(shù)據(jù)包的發(fā)送和接收更為高效,且這個(gè)環(huán)形緩沖區(qū)可以在內(nèi)核態(tài)和用戶態(tài)之間共享。在利用套接字收發(fā)數(shù)據(jù)時(shí),每個(gè)數(shù)據(jù)包會(huì)存放在一個(gè)單獨(dú)的幀(frame)中,多個(gè)幀會(huì)被分組形成內(nèi)存塊(block)。CVE-2017-7308 漏洞存在于內(nèi)核處理版本為TPACKET_V3 的環(huán)形緩沖區(qū)的代碼中,由于內(nèi)核在判斷接收到數(shù)據(jù)的長度時(shí)存在整數(shù)溢出,使其通過長度的安全性檢查而導(dǎo)致堆溢出漏洞。攻擊者可以通過溢出控制函數(shù)指針來劫持內(nèi)核的控制流。利用該內(nèi)核漏洞進(jìn)一步實(shí)現(xiàn)容器逃逸的攻擊流程如下。

        1) 通過/proc/kallsyms 或syslog 的方式泄露內(nèi)核函數(shù)地址來獲得內(nèi)核的加載基址,繞過內(nèi)核KASLR 保護(hù)機(jī)制。

        2) 構(gòu)造堆布局觸發(fā)內(nèi)核處理環(huán)形緩沖區(qū)代碼packet_set_ring()中的堆溢出漏洞。

        3) 覆蓋packet_socket 結(jié)構(gòu)體中的retire_blk_timer 字段,使該字段中的函數(shù)指針func 指向native_write_cr4()。同時(shí),覆蓋該字段中的data 為函數(shù)native_write_cr4()的參數(shù)。若計(jì)時(shí)器超時(shí),執(zhí)行native_write_cr4()來禁用SMEP 和SMAP。

        4) 以同樣的方式構(gòu)造堆溢出,覆蓋packet_sock中的xmit 字段,使其指向攻擊載荷函數(shù)get_root_payload()。

        5) 在 get_root_payload()函數(shù)中首先執(zhí)行commit_creds()來提升容器內(nèi)當(dāng)前進(jìn)程的權(quán)限;然后,執(zhí)行switch_task_namespaces()來切換容器內(nèi)已提權(quán)進(jìn)程的namespaces,實(shí)現(xiàn)逃逸。由表1 可知,HOC-Detector 和NS-Detector 均能檢測(cè)到利用漏洞CVE-2017-7308 實(shí)現(xiàn)的逃逸行為。HOC-Detector 對(duì)利用漏洞CVE-2017-7308實(shí)現(xiàn)的容器逃逸過程進(jìn)行監(jiān)測(cè)所獲取的觀測(cè)鏈如圖8 所示。攻擊者通過運(yùn)行逃逸攻擊程序exploit 獲得一個(gè)root 權(quán)限的進(jìn)程(pid=3046)。其中,進(jìn)程(pid=3045)執(zhí)行系統(tǒng)調(diào)用clone 產(chǎn)生新進(jìn)程(pid=3046)的操作存在權(quán)限提升。漏洞CVE-2017-7308 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化如表2 所示。其中,容器內(nèi)的進(jìn)程(主體T,pid=3045)復(fù)制出的子進(jìn)程(客體H,pid=3046)在所有觀測(cè)點(diǎn)的值均與宿主機(jī)上1 號(hào)進(jìn)程的值相等()=1,0 ≤i≤ 6),即FAC=7,說明出現(xiàn)了權(quán)限提升,HOC-Detector 可以檢測(cè)出利用該內(nèi)核漏洞實(shí)現(xiàn)的直接逃逸行為。由于獲得的逃逸進(jìn)程(pid=3046)是容器中進(jìn)程(pid=3045)的子進(jìn)程,且兩者的namespaces 不一致,NS-Detector 也能檢測(cè)到該逃逸行為。

        表2 漏洞CVE-2017-7308 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化

        圖8 HOC-Detector 對(duì)利用漏洞CVE-2017-7308 實(shí)現(xiàn)的容器逃逸過程進(jìn)行監(jiān)測(cè)所獲取的觀測(cè)鏈

        4.3 CVE-2017-18344 和CVE-2017-1000112

        CVE-2017-18344 存在于Linux 內(nèi)核4.14.8 之前的版本中,在系統(tǒng)調(diào)用 timer_create 的實(shí)現(xiàn)kernel/time/posix-timers.c 中沒有正確驗(yàn)證結(jié)構(gòu)體sigevent 中的字段sigev_notify,存在整型溢出漏洞。當(dāng)用戶讀取/proc/pid/timers 中的內(nèi)容時(shí),可以利用該漏洞在posix-timers.c 的函數(shù)show_timer()中實(shí)現(xiàn)越界訪問,進(jìn)一步使用戶態(tài)程序可以讀取內(nèi)核中任意地址的內(nèi)容。CVE-2017-1000112 存在于Linux 內(nèi)核 4.13.9 之前的版本中,該漏洞位于/net/ipv4/ip_output.c 中的__ip_append_data(),漏洞形成的原因是內(nèi)核通過標(biāo)志SO_NO_CHECK 來判斷在處理數(shù)據(jù)包時(shí)是使用UFO 機(jī)制還是non-UFO機(jī)制(UFO 機(jī)制是指用網(wǎng)卡輔助進(jìn)行報(bào)文分片,用戶層協(xié)議不進(jìn)行分片;non-UFO 機(jī)制是指在用戶層進(jìn)行報(bào)文分片)。具體來說,第一次調(diào)用send()函數(shù)發(fā)送數(shù)據(jù)包時(shí),本文可以發(fā)送一個(gè)大小超過MTU的數(shù)據(jù)包,這將執(zhí)行UFO 的處理邏輯。在第二次調(diào)用 send()發(fā)送數(shù)據(jù)包之前,先執(zhí)行系統(tǒng)調(diào)用setsockopt 來設(shè)置 SO_NO_CHECK,使其執(zhí)行non-UFO 的處理邏輯,觸發(fā)_ip_append_data()函數(shù)中的越界寫漏洞。攻擊者可以利用這2 個(gè)內(nèi)核漏洞實(shí)現(xiàn)間接容器逃逸,其攻擊流程如下。

        1) 構(gòu)造堆布局觸發(fā)CVE-2017-18344,實(shí)現(xiàn)任意地址讀,泄露中斷描述符表(IDT,interrupt descriptor table)第一項(xiàng)(divide_error)的地址,并根據(jù)它的地址計(jì)算出內(nèi)核的加載基址,繞過內(nèi)核KASLR 保護(hù)機(jī)制。

        2) 利用CVE-2017-1000112 實(shí)現(xiàn)任意地址寫,劫持控制流至攻擊載荷函數(shù)get_root_payload()。

        3) 在 get_root_payload()函數(shù)中首先執(zhí)行commit_creds()函數(shù)來提升容器內(nèi)當(dāng)前進(jìn)程的權(quán)限;然后,執(zhí)行_copy_fs_struct()函數(shù)來將當(dāng)前進(jìn)程的根目錄切換為宿主機(jī)上1 號(hào)進(jìn)程的根目錄。

        4) 在宿主機(jī)目錄/var/spool/cron/crontabs/下創(chuàng)建文件root,向其中寫入開啟反彈shell 的代碼:echo′ * * * * * bash -c " bash -i >&/dev/tcp/IP/PORT 0>&1 " ′ >> root。

        5) 攻擊者在受控端執(zhí)行nc-vnlp 12345 等待容器所在宿主機(jī)反彈shell 的連接,獲取一個(gè)root 權(quán)限的反彈shell,實(shí)現(xiàn)逃逸。

        由表1 可知,HOC-Detector 可以檢測(cè)出該逃逸行為,而NS-Detector 則不可以。HOC-Detector 對(duì)利用漏洞CVE-2017-18344 和CVE-2017-1000112實(shí)現(xiàn)的容器逃逸過程進(jìn)行監(jiān)測(cè)所獲取的觀測(cè)鏈如圖9 所示,在階段2 中,漏洞利用程序exploit 首先執(zhí)行 touch 命令,在宿主機(jī)目錄/var/spool/cron/crontabs 下新建文件root,隨后執(zhí)行write 系統(tǒng)調(diào)用向其寫入內(nèi)容。宿主機(jī)上的進(jìn)程(pid=1121)讀取root 文件中的內(nèi)容,隨后通過執(zhí)行connect 系統(tǒng)調(diào)用與遠(yuǎn)端(攻擊者控制)建立socket 連接,開啟一個(gè)root 權(quán)限的反彈shell。漏洞CVE-2017-18344 和CVE-2017-10000112 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化如表3 所示,容器內(nèi)進(jìn)程(主體T,pid=2874)復(fù)制出子進(jìn)程(客體H,pid=2798),子進(jìn)程的fs_root、uid、gid、cap_permitted 均變?yōu)樗拗鳈C(jī)1 號(hào)進(jìn)程對(duì)應(yīng)的值()=1,0 ≤i≤ 3),即FAC=4,說明該操作存在權(quán)限提升。同時(shí),容器內(nèi)的進(jìn)程(pid=2798)所執(zhí)行的5.create 和6.write 均是對(duì)宿主機(jī)上的文件進(jìn)行操作,也存在權(quán)限提升,HOC-Detector 可以檢測(cè)到該間接逃逸攻擊。

        表3 漏洞CVE-2017-18344 和CVE-2017-10000112 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化

        圖9 HOC-Detector 對(duì)利用漏洞CVE-2017-18344 和CVE-2017-1000112 實(shí)現(xiàn)的容器逃逸過程進(jìn)行監(jiān)測(cè)所獲取的觀測(cè)鏈

        NS-Detecoor 認(rèn)為逃逸進(jìn)程屬于容器進(jìn)程的子進(jìn)程,且其Namespaces 與宿主機(jī)1 號(hào)進(jìn)程的namespaces 一致。在本次實(shí)驗(yàn)中,雖然容器內(nèi)進(jìn)程的namespcae 在圖9 中的操作(3.clone)前后發(fā)生變化,如表3 所示,子進(jìn)程(pid=2798)與父進(jìn)程(pid=2784)的net_ns 不一致,但子進(jìn)程(pid=2798)的namespaces 與宿主機(jī)1 號(hào)進(jìn)程不一致。即在本次間接逃逸攻擊中,容器內(nèi)新創(chuàng)建進(jìn)程的namespaces與宿主機(jī)1 號(hào)進(jìn)程的namespaces 不一致,NS-Detector不能檢測(cè)出該間接逃逸行為。此外,圖9 中階段3得到的逃逸進(jìn)程(pid=2845)是宿主機(jī)上cron 進(jìn)程的子進(jìn)程,而非容器進(jìn)程的子進(jìn)程。

        4.4 CVE-2016-5195

        CVE-2016-5195(臟牛漏洞)是一個(gè)寫時(shí)復(fù)制的條件競爭漏洞,影響Linux 內(nèi)核4.8.3 之前的版本。條件競爭[25]是指一個(gè)系統(tǒng)的運(yùn)行結(jié)果依賴于不受控制的事件的先后順序,通常發(fā)生在多個(gè)進(jìn)程(線程)同時(shí)訪問和操作相同的數(shù)據(jù)時(shí)。寫時(shí)復(fù)制[26]允許不同進(jìn)程中的虛擬內(nèi)存映射到相同物理內(nèi)存頁面的技術(shù)。寫時(shí)復(fù)制一般包含3 個(gè)重要步驟:創(chuàng)建映射內(nèi)存的副本;更新頁表,使虛擬內(nèi)存指向新創(chuàng)建的物理內(nèi)存;寫入內(nèi)存。由于這3個(gè)步驟不是原子性的,一個(gè)進(jìn)程在執(zhí)行這3 個(gè)步驟過程中可能被其他進(jìn)程中斷,從而觸發(fā)寫時(shí)復(fù)制的條件競爭。

        攻擊者可利用臟牛漏洞實(shí)現(xiàn)對(duì)vDSO[16]的任意寫,從而劫持控制流實(shí)現(xiàn)容器逃逸。vDSO 是內(nèi)核提供的虛擬動(dòng)態(tài)鏈接庫(.so),當(dāng)程序啟動(dòng)時(shí),內(nèi)核把vDSO映射入進(jìn)程內(nèi)存空間,程序?qū)⑵洚?dāng)作普通動(dòng)態(tài)庫來調(diào)用其中的函數(shù)。在Docker 容器中,本文通過利用寫時(shí)復(fù)制的條件競爭漏洞(臟牛漏洞)實(shí)現(xiàn)對(duì)vDSO 的任意寫,將vDSO 中的函數(shù)clock_gettime()用shellcode覆蓋,進(jìn)而實(shí)現(xiàn)容器逃逸,具體流程如下。

        1) 創(chuàng)建一個(gè)具有capability SYS_PTRACE 的容器。這是因?yàn)槁┒蠢么a使用PTRACE 進(jìn)行代碼注入,但是Docker 在容器啟動(dòng)時(shí)默認(rèn)過濾了SYS_PTRACE。

        2) 運(yùn)行漏洞利用代碼,它將創(chuàng)建2 個(gè)線程ptrace_thread 和madvise_thread。

        3) 線程ptrace_thread 利用ptrace 不斷向vDSO寫入數(shù)據(jù)。

        4) 線程madvise_thread 不斷執(zhí)行madvise 系統(tǒng)調(diào)用,將vDSO 地址空間標(biāo)記為MADV_ DONTNEED,內(nèi)核將會(huì)釋放vDSO 所在內(nèi)存區(qū)域,進(jìn)程的頁表會(huì)重新指向原始的物理內(nèi)存。

        5) 由線程ptrace_thread 和madvise_thread 觸發(fā)寫時(shí)復(fù)制的條件競爭漏洞,實(shí)現(xiàn)向只讀內(nèi)存區(qū)域?qū)懭霐?shù)據(jù)的功能,即用shellcode 覆蓋vDSO 中的函數(shù)clock_gettime()。

        6) shellcode 會(huì)檢查是否是root 權(quán)限進(jìn)程在調(diào)用clock_gettime 函數(shù),若是,則開啟一個(gè)root 權(quán)限反彈shell;若不是,則執(zhí)行原來的clock_gettime()函數(shù)。

        本次實(shí)驗(yàn)結(jié)果和前一個(gè)間接逃逸的實(shí)驗(yàn)結(jié)果一致,HOC-Detector 可以檢測(cè)出該逃逸行為,而NS-Detector 則不可以。HOC-Detector 監(jiān)控利用該漏洞進(jìn)行逃逸的流程,得到如圖10 所示的觀測(cè)鏈。攻擊者執(zhí)行漏洞利用代碼deadbeef,用shellcode 覆蓋 vDSO 中的函數(shù) clock_gettime()后,進(jìn)程containerd-shim 在某時(shí)刻執(zhí)行函數(shù)clock_gettime()開啟一個(gè) root 權(quán)限的 shell(pid=1738)。漏洞CVE-2016-5195 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化如表4 所示,由于該逃逸行為并未執(zhí)行內(nèi)核函數(shù)commit_creds()來進(jìn)行提權(quán),因此 uid、gid 和cap_permitted 的值并未變化。在內(nèi)核中讀取子進(jìn)程(pid=1739)的fs_root 和namespcae 相關(guān)屬性時(shí),其相關(guān)的指針為空,本文將其屬性值標(biāo)記為None。本文認(rèn)為屬性值為None 是僅低于root 權(quán)限的屬性值。容器內(nèi)進(jìn)程(主體T,pid=21729)復(fù)制出子進(jìn)程(客體H,pid=1739),子進(jìn)程的fs_root、mnt_ns、pid_ns、net_ns 均比父進(jìn)程對(duì)應(yīng)的值大()=1,i∈ [0,4,5,6]),即FAC=4,說明該操作存在權(quán)限提升,HOC-Detector 可以檢測(cè)到該間接逃逸攻擊。另外,containerd-shim 進(jìn)程(pid=1670)的任務(wù)是用來啟動(dòng)一個(gè)容器,但它通過執(zhí)行3.fork 創(chuàng)建了一個(gè)root 權(quán)限的bash 進(jìn)程(逃逸進(jìn)程,pid=1738),超出其原有能力范圍,從此角度看,該操作也存在權(quán)限提升。

        表4 漏洞CVE-2016-5195 權(quán)限提升操作處的觀測(cè)點(diǎn)屬性變化

        圖10 HOC-Detector 對(duì)利用漏洞CVE-2016-5195 實(shí)現(xiàn)的容器逃逸過程進(jìn)行監(jiān)測(cè)所獲取的觀測(cè)鏈

        在本次實(shí)驗(yàn)中,NS-detector 不能檢測(cè)到容器逃逸攻擊的原因與4.3 節(jié)中的實(shí)驗(yàn)一樣。容器內(nèi)新創(chuàng)建子進(jìn)程的namespaces 并不等于宿主機(jī)1 號(hào)進(jìn)程的namespaces,且最后獲得的 root 權(quán)限逃逸進(jìn)程(pid=1738)不是容器內(nèi)進(jìn)程的子進(jìn)程。綜合分析4.3 節(jié)和4.4 節(jié)中的2 個(gè)實(shí)驗(yàn),NS-Detector 無法檢測(cè)到間接逃逸攻擊的根本原因在于它對(duì)容器逃逸行為的畫像不夠全面,僅關(guān)注容器內(nèi)的進(jìn)程和它們的namespaces。HOC-Detector 通過收集宿主機(jī)上所有進(jìn)程的行為信息,提取與容器內(nèi)進(jìn)程所有相關(guān)的操作構(gòu)建觀測(cè)鏈。同時(shí),本文經(jīng)過大量復(fù)現(xiàn)內(nèi)核逃逸后提煉出一些具代表性的觀測(cè)點(diǎn),實(shí)現(xiàn)對(duì)容器內(nèi)進(jìn)程全生命周期的異構(gòu)觀測(cè),使其具備檢測(cè)間接逃逸攻擊的能力。

        4.5 性能開銷

        4.5.1 實(shí)驗(yàn)設(shè)置

        本文的性能評(píng)估方式與CLARION[27]類似,使用基于容器的微服務(wù)數(shù)據(jù)集對(duì) SPADE 和HOC-Detector 進(jìn)行性能開銷的評(píng)估。本文使用谷歌提供的一個(gè)知名的微服務(wù)集Online Boutique[28]作為本文的數(shù)據(jù)集。該數(shù)據(jù)集目前包含11 個(gè)用不同編程語言編寫的微服務(wù),這些微服務(wù)通過gRPC 相互通信。

        4.5.2 運(yùn)行時(shí)開銷

        為了評(píng)估HOC-Detector 的運(yùn)行開銷,本文獨(dú)立地啟動(dòng)每個(gè)微服務(wù)50 次,并記錄這50 個(gè)容器微服務(wù)初始化的累計(jì)時(shí)間。首先,本文在沒有啟動(dòng)Linux Audit 的情況下執(zhí)行這一流程,以獲得一個(gè)基礎(chǔ)測(cè)試時(shí)間。然后,本文分別用Linux Audit、SPADE和HOC-Detector 重復(fù)這一流程。運(yùn)行時(shí)開銷比較如表5 所示。其中,增量開銷是通過對(duì)比HOC-Detector和SPADE 的開銷計(jì)算得到的,而總體開銷則是HOC-Detector 與基礎(chǔ)測(cè)試的性能比較。本文系統(tǒng)HOC-Detector 基于SPADE 實(shí)現(xiàn),帶來的額外增量開銷低于9%,本文認(rèn)為這是可以接受的。

        表5 運(yùn)行時(shí)開銷比較

        HOC-Detector 的總體開銷包括SPADE 原有的開銷和HOC-Detector 通過內(nèi)核模塊提取進(jìn)程生命周期中觀測(cè)點(diǎn)的開銷。通過和Base 的開銷數(shù)值進(jìn)行比較,HOC-Detector 引入的總體開銷平均增加37.3%,對(duì)容器的單次啟動(dòng)開銷增加0.75%。經(jīng)過分析可發(fā)現(xiàn),增加的開銷主要來自SPADE,而不是HOC-Detector 通過內(nèi)核模塊獲取進(jìn)程運(yùn)行時(shí)信息的開銷。

        5 結(jié)束語

        針對(duì)利用內(nèi)核漏洞的容器逃逸攻擊,本文提出了一種容器逃逸檢測(cè)技術(shù)HOC-Detector,通過在內(nèi)核中監(jiān)視進(jìn)程的行為和提取關(guān)鍵進(jìn)程屬性信息,增強(qiáng)了系統(tǒng)對(duì)攻擊行為的實(shí)時(shí)檢測(cè)能力,降低了信息捕捉時(shí)延。其次,HOC-Detector 基于進(jìn)程行為信息構(gòu)建進(jìn)程起源圖,將進(jìn)程關(guān)鍵的屬性信息作為觀測(cè)點(diǎn),對(duì)容器進(jìn)程的全生命周期進(jìn)行異構(gòu)觀測(cè)。最后,HOC-Detector 通過檢測(cè)容器中的進(jìn)程行為是否有權(quán)限提升來判斷當(dāng)前進(jìn)程是否在實(shí)施容器逃逸攻擊。實(shí)驗(yàn)結(jié)果表明,HOC-Detector 能成功檢測(cè)到直接逃逸和間接逃逸攻擊,并且能應(yīng)對(duì)不同的攻擊方式。同時(shí),經(jīng)過本文的性能開銷測(cè)試,HOC-Detector對(duì)容器單次啟動(dòng)增加的開銷約為0.75%,不會(huì)對(duì)整個(gè)系統(tǒng)造成較大影響。目前,HOC-Detector 還存在一些不足之處。首先,HOC-Detector 僅使用Docker容器下的內(nèi)核漏洞逃逸,尚未對(duì)其他容器引擎進(jìn)行測(cè)試。其次,針對(duì)提取進(jìn)程行為、屬性信息的內(nèi)核模塊,本文尚未涉及對(duì)其安全性的討論。這些都將作為筆者未來的工作進(jìn)一步深入研究。

        猜你喜歡
        進(jìn)程檢測(cè)
        “不等式”檢測(cè)題
        “一元一次不等式”檢測(cè)題
        “一元一次不等式組”檢測(cè)題
        “幾何圖形”檢測(cè)題
        “角”檢測(cè)題
        債券市場(chǎng)對(duì)外開放的進(jìn)程與展望
        中國外匯(2019年20期)2019-11-25 09:54:58
        小波變換在PCB缺陷檢測(cè)中的應(yīng)用
        我國高等教育改革進(jìn)程與反思
        Linux僵死進(jìn)程的產(chǎn)生與避免
        男女平等進(jìn)程中出現(xiàn)的新矛盾和新問題
        精品久久久久久无码中文野结衣 | 青草网在线观看| 国产精品日韩中文字幕| 成年人视频在线播放视频| 亚洲女同系列在线观看| 人妻丰满熟av无码区hd| 色翁荡息又大又硬又粗又视频图片| 国产精品青草久久久久婷婷| 中文字幕亚洲视频三区| 青青草大香蕉视频在线观看| 亚洲国产欧美日韩欧美特级| 日韩毛片基地一区二区三区| 大白屁股流白浆一区二区三区| 亚洲熟妇av一区二区在线观看| 成午夜精品一区二区三区| 鲁一鲁一鲁一鲁一澡| 亚洲成人欧美| 亚洲一区二区丝袜美腿| 午夜视频国产在线观看| 欧美成人免费全部| av无码av在线a∨天堂app| 国产精品午夜福利亚洲综合网 | 日本一区人妻蜜桃臀中文字幕 | 中文字幕 亚洲精品 第1页| 日本亚洲色大成网站www久久| 中文字幕avdvd| 中文字幕在线亚洲精品一区| 国产欧美va欧美va香蕉在| 国产精品成人av在线观看| 蜜桃av观看亚洲一区二区| 日本久久久免费观看视频| 香蕉人人超人人超碰超国产| 在线观看av手机网址| 亚洲福利一区二区不卡| av成人综合在线资源站| 国产亚洲自拍日本亚洲| 久久久久久国产精品无码超碰动画 | 日韩性爱视频| 国产午夜三级一区二区三| 久久99国产亚洲高清观看首页| 人妻少妇精品视频一区二区三|