• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    運(yùn)行時代碼隨機(jī)化防御代碼復(fù)用攻擊*

    2019-10-24 05:50:02張貴民李清寶曾光裕趙宇韜
    軟件學(xué)報 2019年9期
    關(guān)鍵詞:攻擊者內(nèi)存代碼

    張貴民,李清寶,曾光裕,趙宇韜

    1(解放軍信息工程大學(xué),河南 鄭州 450001)

    2(數(shù)學(xué)工程與先進(jìn)計算國家重點實驗室,河南 鄭州 450001)

    通訊作者:張貴民,E-mail:zh.guimin@163.com

    代碼復(fù)用攻擊(code reuse attack,簡稱CRA)已成為當(dāng)前一種廣泛應(yīng)用的主流攻擊.CRA 首先在內(nèi)存中的已有代碼中尋找可用的指令序列(即gadgets),然后劫持控制流,使這些gadgets 得到執(zhí)行,從而實現(xiàn)攻擊.由于并不植入任何代碼,因此能夠輕易繞過數(shù)據(jù)執(zhí)行阻止技術(shù)(data executive prevention,簡稱DEP)[1].

    地址空間布局隨機(jī)化技術(shù)(address space layout randomization,簡稱ASLR)[2]是防御代碼復(fù)用攻擊的一類重要技術(shù),已在當(dāng)前的大部分操作系統(tǒng)中得到應(yīng)用.ASLR 通過對代碼段和數(shù)據(jù)段的基地址的隨機(jī)化,使攻擊者無法定位相關(guān)指令序列.但之后提出的暴力破解攻擊[3]和基于內(nèi)存泄漏漏洞[4]實現(xiàn)的攻擊,成功突破了ASLR 防護(hù)技術(shù).為進(jìn)一步提高ASLR 的防御能力,更細(xì)粒度的隨機(jī)化技術(shù)[5-8]被不斷提出,通過進(jìn)一步增加代碼或指令的隨機(jī)性,阻止攻擊者獲得gadgets 信息.但隨后,Snow 等人提出了即使在細(xì)粒度ASLR 下也能實現(xiàn)的JIT-ROP 攻擊[9].JIT-ROP 攻擊的成功在于現(xiàn)有ASLR 普遍采用程序運(yùn)行前的一次代碼隨機(jī)化,而運(yùn)行過程中代碼在內(nèi)存中的位置則相對固定,攻擊者可借助內(nèi)存泄漏漏洞動態(tài)地分析內(nèi)存中的代碼以獲取gadgets 的信息.

    為更好地防御復(fù)雜先進(jìn)的代碼復(fù)用攻擊,如JIT-ROP 攻擊等,本文提出一種基于運(yùn)行時代碼隨機(jī)化的代碼復(fù)用攻擊防御方法LCR.其基本原理是:允許攻擊者獲取內(nèi)存信息,但在攻擊者利用這些信息實施攻擊之前使這些信息失效,從而導(dǎo)致攻擊失敗.該方法監(jiān)控對目標(biāo)程序代碼段的讀數(shù)據(jù)操作和該程序執(zhí)行的輸入類系統(tǒng)調(diào)用,當(dāng)發(fā)生上述操作時,則對程序代碼中各函數(shù)塊在內(nèi)存中的位置進(jìn)行隨機(jī)變換,使攻擊者通過直接內(nèi)存泄漏或間接內(nèi)存泄漏[10]獲得的內(nèi)存信息無效,從而阻止攻擊者根據(jù)泄漏的信息實現(xiàn)代碼復(fù)用攻擊.最后,本文借助硬件虛擬化技術(shù)Intel VT[11]設(shè)計實現(xiàn)了LCR 的原型系統(tǒng),并對該方法的有效性和性能開銷進(jìn)行了測試,結(jié)果表明:LCR能夠有效防御包含JIT-ROP 在內(nèi)的大多數(shù)代碼復(fù)用攻擊,且在SPEC CPU2006 上的平均開銷低于5%.

    本文第1 節(jié)描述LCR 的威脅模型和假設(shè),明確防御對象和實施條件.第2 節(jié)簡要介紹LCR 的總體架構(gòu).第3節(jié)論述LCR 的具體設(shè)計和實現(xiàn)方法.第4 節(jié)實現(xiàn)LCR 原型系統(tǒng)并對其進(jìn)行測試.第5 節(jié)探討LCR 的局限性.第6 節(jié)對比分析LCR 和其他相關(guān)的研究工作.第7 節(jié)對全文工作進(jìn)行總結(jié).

    1 威脅模型和假設(shè)

    LCR 旨在保護(hù)目標(biāo)程序免遭代碼復(fù)用攻擊,即使是如JIT-ROP 這樣功能強(qiáng)大的攻擊也無法在有LCR 保護(hù)的情況下得以實現(xiàn).LCR 的威脅模型和假設(shè)為:

    (1)目標(biāo)程序中至少含有一個內(nèi)存損壞漏洞,攻擊者能夠借助該漏洞實現(xiàn)對目標(biāo)程序內(nèi)存的任意讀寫以及對目標(biāo)程序控制流的劫持;

    (2)攻擊者可以獲取和分析目標(biāo)程序的二進(jìn)制文件;

    (3)操作系統(tǒng)已開啟ASLR 和DEP 機(jī)制,攻擊者不能通過植入代碼實現(xiàn)攻擊;

    (4)系統(tǒng)的硬件設(shè)備是可信的;

    (5)只考慮針對應(yīng)用程序的代碼復(fù)用攻擊,針對內(nèi)核層和虛擬層的攻擊不在考慮范圍內(nèi).

    本文與其他相關(guān)代碼復(fù)用攻擊的防御方法[12,13]所采用的攻擊模型和假設(shè)基本一致.

    2 總體架構(gòu)

    LCR 的目的是使攻擊者通過內(nèi)存泄漏等方式得到的關(guān)于程序代碼的內(nèi)存信息失效,而利用這些失效的信息,攻擊者無法成功發(fā)動代碼復(fù)用攻擊.在目標(biāo)程序運(yùn)行過程中,LCR 動態(tài)地對目標(biāo)程序代碼的內(nèi)存布局進(jìn)行隨機(jī)化變換,其總體架構(gòu)如圖1 所示.

    LCR 總體分為3 個階段.

    · 一是預(yù)處理階段:重新編譯目標(biāo)程序,獲取與隨機(jī)化處理相關(guān)的程序代碼信息;

    · 二是運(yùn)行時監(jiān)控階段:在發(fā)現(xiàn)對程序代碼所在內(nèi)存頁的讀數(shù)據(jù)操作和執(zhí)行輸入類操作時,觸發(fā)對目標(biāo)程序代碼的隨機(jī)化處理,實現(xiàn)對代碼復(fù)用攻擊的有效防御;

    · 三是運(yùn)行時代碼隨機(jī)化處理階段:采用對目標(biāo)程序代碼段中各函數(shù)塊所處內(nèi)存位置重排序的方式,打亂原有代碼中所有指令的內(nèi)存地址,使攻擊者在變化前獲取的內(nèi)存分布信息失效,當(dāng)攻擊者利用這些失效的信息發(fā)動代碼復(fù)用攻擊時,導(dǎo)致攻擊失?。煌瑫r,該階段還要完成對所有相關(guān)指針、代碼等內(nèi)容的更新操作,以保證變換后程序仍能正常運(yùn)行.

    本文借助Intel VT 硬件虛擬化技術(shù)[11]對LCR 進(jìn)行了設(shè)計和實現(xiàn).LCR 的核心功能模塊,即觸發(fā)事件監(jiān)控模塊和隨機(jī)化處理模塊,均在一個輕量級Hypervisor 中實現(xiàn).

    Fig.1 Overall architecture of LCR圖1 LCR 的總體架構(gòu)

    3 LCR 的設(shè)計與實現(xiàn)

    3.1 預(yù)處理

    在對目標(biāo)進(jìn)程代碼段中的函數(shù)塊進(jìn)行隨機(jī)化處理后,函數(shù)塊的絕對地址以及各函數(shù)塊之間的相對位置都將改變,因此,某些指令中使用的相關(guān)地址參數(shù)和偏移量以及指向各函數(shù)的指針類型變量都需要進(jìn)行更新.預(yù)處理階段獲取需要更新的指令和變量的信息,為隨機(jī)化后的更新提供依據(jù).

    為盡量降低隨機(jī)化后內(nèi)容更新的復(fù)雜度,采用了地址無關(guān)代碼(position-independent code,簡稱PIC)和地址無關(guān)可執(zhí)行(position-independent executable,簡稱PIE)技術(shù),在編譯時增加-fpic 或-pie 選項即可.PIC/PIE 對常量和函數(shù)入口地址的操作都基于基寄存器+偏移量的相對地址的尋址方式,有利于代碼隨機(jī)化的實現(xiàn).采用PIC/PIE 技術(shù)在一定程度上簡化了隨機(jī)化變換后的處理,但仍要對目標(biāo)進(jìn)程的某些代碼和數(shù)據(jù)進(jìn)行更新操作.

    3.1.1 代碼段中相關(guān)內(nèi)容

    為便于分析,這里引入模塊的概念,將一個采用動態(tài)鏈接程序的每個可執(zhí)行文件和共享對象都看做是該程序的一個模塊,而將采用靜態(tài)鏈接的程序看做一個獨立模塊.

    (1)函數(shù)塊內(nèi)的代碼引用

    由于隨機(jī)化處理時將函數(shù)塊作為一個整體進(jìn)行移動,函數(shù)塊內(nèi)順序執(zhí)行部分不受影響,因此主要考慮非順序執(zhí)行的內(nèi)容,即分支指令,包括CALL,JCC(如JA,JAE,JC,JRCXZ 等),JMP 和LOOP[11]這4 類.分支指令只能跳轉(zhuǎn)到同一個函數(shù)內(nèi)部的某條指令或者另一個函數(shù)的入口,正常情況下不能跳轉(zhuǎn)到其他函數(shù)內(nèi)部.在這里僅考慮內(nèi)部跳轉(zhuǎn),跳轉(zhuǎn)到其他函數(shù)入口的情況在情形(2)中討論.而上述指令在函數(shù)塊中使用時,都通過由相對于當(dāng)前指令指針值(存放在EIP 寄存器中)的偏移值確定目的指令.由于隨機(jī)化前后函數(shù)塊內(nèi)的指令順序不變,因此指令間的相對偏移也不變,所以該類指令在隨機(jī)化后不需要更新.

    (2)模塊內(nèi)的函數(shù)調(diào)用

    同一模塊內(nèi)的函數(shù)調(diào)用通過CALL 指令或跳轉(zhuǎn)指令實現(xiàn).對于CALL 指令和JMP 指令,當(dāng)以寄存器直接或間接尋址時,由于LCR 并不改變目標(biāo)進(jìn)程的執(zhí)行流程,寄存器中的內(nèi)容與隨機(jī)化變換前一致,因此該類指令不需要修正;而當(dāng)采用相對于指令指針或程序代碼段基地址的偏移值定位目的指令時,則需要根據(jù)該指令的下一條指令與被調(diào)用函數(shù)在隨機(jī)化變換之后的位置關(guān)系計算新的偏移值.對于JCC 和LOOP 指令,均采用相對于當(dāng)前指令指針值的偏移,同樣需要重新計算偏移值.

    為了便于在隨機(jī)化后執(zhí)行上述操作,需提取相關(guān)指令的地址信息,同時記錄目標(biāo)程序代碼中各個函數(shù)塊在隨機(jī)化變換前后的布局信息.為此,在預(yù)處理階段,通過分析目標(biāo)程序的匯編指令獲取代碼段中的各個函數(shù)的名稱、起始地址和長度,并構(gòu)造一個原始的函數(shù)布局信息表.而在每次隨機(jī)化變換時,都將生成一個新的布局信息表,并按照該表對代碼進(jìn)行隨機(jī)化變換.通過新舊布局信息表即可計算出所需的各類數(shù)據(jù).例如,假設(shè)某次變換時原始表和新表見表1,那么原來跳轉(zhuǎn)到func1(0x55c)的跳轉(zhuǎn)指令使用的偏移值只需更新為指令指針值與地址0x582 的偏移值即可.

    Table 1 Function blocks layout information table表1 函數(shù)布局信息表

    (3)模塊間的函數(shù)調(diào)用

    模塊間的函數(shù)調(diào)用依賴程序鏈接表(procedure linkage table,簡稱PLT)和全局偏移表(global offset table,簡稱GOT)實現(xiàn).ELF 文件將GOT 拆分成“.got”和“.got.plt”兩個表,分別保存全局變量和函數(shù)的地址.下面以程序exam.c 為例(exam.c 的源代碼以及部分匯編代碼、符號表及調(diào)試信息如圖2 所示),分析在x86 架構(gòu)下采用PIC/PIE 進(jìn)行編譯生成共享庫(共享庫默認(rèn)即為PIC)和可執(zhí)行代碼時的函數(shù)調(diào)用機(jī)制.

    Fig.2 Relevant files for exam圖2 程序exam 的相關(guān)文件

    由匯編代碼可知:exam 調(diào)用共享庫函數(shù)時,首先執(zhí)行圖2③中的兩條指令.由圖2①中函數(shù)__i686.get_pc_thunk.bx 的定義可知,該函數(shù)獲取0x627 處的指令在內(nèi)存中的實際內(nèi)存地址并存放于ebx 中.通過符號表(如圖2④所示)可知,.got.plt 與0x627 處指令的偏移正好為0x19cd.因此,0x627 處指令獲取.got.plt 的實際內(nèi)存地址并存放在ebx 中.程序之后對共享庫中內(nèi)容的調(diào)用都基于相對于.got.plt 的偏移實現(xiàn).由于LCR 并不改變數(shù)據(jù)段(含.got.plt),在隨機(jī)化后該偏移值不變,因此只需重新計算調(diào)用__i686.get_pc_thunk.bx 函數(shù)的那條指令的下一條指令(本例中為0x627)與.got.plt 地址(本例中為0x1ff4)的相對偏移(本例中為0x19cd),并用該值替換原參數(shù),即可保證程序仍能夠定位到.got.plt.

    (4)訪問數(shù)據(jù)的指令

    對數(shù)據(jù)的訪問同樣分為模塊內(nèi)和模塊間兩種情況:模塊內(nèi)的數(shù)據(jù)訪問采用相對尋址方式實現(xiàn),由于一個模塊中的代碼段和數(shù)據(jù)段的相對位置固定,因此每一條指令和模塊內(nèi)部數(shù)據(jù)之間的相對位置也固定,所以只需在當(dāng)前指令地址的基礎(chǔ)上加一個固定的偏移量即可訪問相應(yīng)數(shù)據(jù),如圖2 中②所示對變量a的訪問方式;模塊間的數(shù)據(jù)訪問由于數(shù)據(jù)地址要等到其所在模塊裝載時才能確定,故該類數(shù)據(jù)訪問基于GOT 實現(xiàn).雖然兩類數(shù)據(jù)訪問方式在理論上有所區(qū)別,但實際實現(xiàn)中都是首先獲取.got.plt 的地址,然后以該地址與要訪問數(shù)據(jù)所在內(nèi)存地址之間的偏移作為指令訪問數(shù)據(jù)的偏移量.因此,在隨機(jī)化后只需重新計算當(dāng)前指令地址的下一條指令與.got.plt 地址的相對偏移(本例中為0x1a1c),并修正相關(guān)指令(本例中為0x5d8 處指令)中的偏移值即可.

    (5)指令指針寄存器(EIP)

    EIP 確定下一步要執(zhí)行指令的地址,在隨機(jī)化變換后,需要對該值進(jìn)行更新以保證后續(xù)指令正常執(zhí)行.首先讀取EIP 的值,然后基于該值和函數(shù)布局信息表判斷其所屬的函數(shù)塊以及該值和函數(shù)塊入口地址的偏移值,然后根據(jù)該函數(shù)塊隨機(jī)化變換后的新地址加上該偏移值計算新的EIP 值,并更新指令指針寄存器.

    (6)回調(diào)函數(shù)相關(guān)指令

    通過把一個函數(shù)的指針作為參數(shù)傳遞給另一個函數(shù)(如atexit,signal,sigaction 以及其他以函數(shù)指針作為參數(shù)的函數(shù)等),當(dāng)該指針被用來調(diào)用其所指向的函數(shù)時,該函數(shù)就稱為回調(diào)函數(shù).當(dāng)目標(biāo)程序中包含回調(diào)函數(shù)時,必定存在相應(yīng)指令將該函數(shù)的指針(即內(nèi)存地址)作為參數(shù)傳遞給其他函數(shù)(通常為movl 指令),即注冊指令.在執(zhí)行代碼隨機(jī)化后,回調(diào)函數(shù)的地址將改變,此時,注冊指令的參數(shù)若不進(jìn)行相應(yīng)更新,當(dāng)回調(diào)函數(shù)被調(diào)用時,將導(dǎo)致程序Crash.因此,必須對這類指令進(jìn)行更新.而根據(jù)隨機(jī)化操作發(fā)生時注冊指令是否已經(jīng)執(zhí)行,可將該類指令分為未執(zhí)行和已執(zhí)行兩類.如圖3 所示,指令Func1(fp3,argu1,argu2)和Func2(fp6,argu3,argu4)分別將fp3 和fp6指向的函數(shù)F3 和F6 注冊為回調(diào)函數(shù),且前者屬于隨機(jī)化操作時已執(zhí)行注冊指令,后者屬于未執(zhí)行注冊指令.

    Fig.3 An example program圖3 例子程序

    對于尚未執(zhí)行的注冊指令,只需在隨機(jī)化發(fā)生時定位到該指令,然后通過原函數(shù)布局信息表定位該指令傳遞的函數(shù)指針?biāo)鶎?yīng)的函數(shù),再在新函數(shù)布局信息表中找到該函數(shù)變換后的新地址,并以該值替換原指令中的指針參數(shù).假設(shè)圖3 中程序的原內(nèi)存布局和隨機(jī)化變換后的新內(nèi)存布局分別如圖4 左上圖和圖4①所示,Func2在隨機(jī)化操作后執(zhí)行時,將直接按更新后F6 的新地址fp6′進(jìn)行回調(diào)函數(shù)的注冊,從而保證程序正常運(yùn)行.

    而對于已執(zhí)行的注冊指令,如圖3 中的Func1,由于該指令已執(zhí)行完畢,此時即使將其參數(shù)fp3 更新為F3 的新地址fp3′也不起作用,當(dāng)程序按照fp3 回調(diào)函數(shù)F3 時,仍將造成程序Crash.為此,提出兩種解決方法.

    1)方法1:在隨機(jī)化操作前,首先分析已經(jīng)執(zhí)行的注冊指令及其注冊的回調(diào)函數(shù);然后,在隨機(jī)化操作時將已注冊函數(shù)進(jìn)行定位和鎖定,保證這些函數(shù)的內(nèi)存地址在隨機(jī)化操作后不發(fā)生改變,只對剩余函數(shù)進(jìn)行隨機(jī)化.其實現(xiàn)機(jī)制如圖4②所示:在隨機(jī)化前后保證函數(shù)F3 的內(nèi)存位置不發(fā)生變化,即fp3=fp3′;而對于尚未注冊的函數(shù)F6 以及其他函數(shù),則進(jìn)行正常的隨機(jī)化.該方法可保證隨機(jī)化操作不影響已注冊回調(diào)函數(shù)的執(zhí)行過程,避免Crash;

    2)方法2:首先,仍要在隨機(jī)化操作前對已經(jīng)注冊的回調(diào)函數(shù)進(jìn)行定位;然后,對所有函數(shù)(包括已注冊函數(shù))進(jìn)行隨機(jī)化.但在隨機(jī)化過程中,向已注冊回調(diào)函數(shù)的原指針指向的內(nèi)存地址處寫入一條jump 指令,將已注冊的回調(diào)函數(shù)的新內(nèi)存地址作為jump 的目的地址.如圖4③所示:在原注冊回調(diào)函數(shù)的內(nèi)存地址fp3 處寫入jump fp3′,從而保證已注冊回調(diào)函數(shù)仍能跳轉(zhuǎn)到正確的內(nèi)存位置處執(zhí)行.

    方法1 簡單高效,但部分代碼的內(nèi)存位置在隨機(jī)化操作后并未發(fā)生改變,這在一定程度上為攻擊者留下了可乘之機(jī);方法2 既能解決已注冊回調(diào)函數(shù)在隨機(jī)化操作后導(dǎo)致的Crash 問題,也保證了隨機(jī)化方法原有的安全性,避免了方法1 導(dǎo)致的安全性降低的問題.但方法2 的實現(xiàn)還涉及多個方面的問題,包括植入jump 指令后內(nèi)存布局被打亂;隨機(jī)化后相關(guān)數(shù)據(jù)的更新方式均需改變;另外,在下一次隨機(jī)化時,如何對待之前植入的jump 指令也是需要解決的問題.本文目前采用方法1,并將在未來工作中對方法2 進(jìn)行研究和實現(xiàn).

    Fig.4 Method to handle callback functions圖4 回調(diào)函數(shù)處理方法

    3.1.2 數(shù)據(jù)相關(guān)內(nèi)容

    (1)函數(shù)指針類型變量

    LCR 改變函數(shù)的入口地址,因此所有指向這些函數(shù)的函數(shù)指針類型變量均需要進(jìn)行修正.由于在C 標(biāo)準(zhǔn)中,函數(shù)指針類型無法由其他類型轉(zhuǎn)換得到,因此可以直接分析目標(biāo)程序中含有的函數(shù)指針類型的全局變量和局部變量.這里,通過在編譯時添加-gdwarf-version 選項(version 為DWARF 的版本號,本文使用-gdwrf-4)生成DWARF 格式的程序調(diào)試信息來實現(xiàn)該分析.程序exam 的部分調(diào)試信息如圖2⑤所示.

    DWARF 中,每條記錄是一個調(diào)試信息入口(debugging information entry,簡稱 DIE),當(dāng)某個 DW_TAG_variable 類型的DIE,又同時屬于指針類型(即DW_TAG_pointer_type)和子過程類型(即DW_TAG_subroutine_type)時,該DIE 對應(yīng)的變量即為函數(shù)指針類型.然后,由該變量的DW_AT_location 屬性即可獲得該變量內(nèi)存地址的計算方法.例如圖2⑤所示,ptr 的實際地址即程序加載地址加上0x2020.不同的DW_AT_location 屬性對應(yīng)各自的變量地址的計算方式[14],因此,通過遍歷DIE 即可找到所有函數(shù)指針類型變量及其地址的計算方法.

    另外,需要特別注意的是:當(dāng)存在結(jié)構(gòu)體struct 和聯(lián)合體union 類型變量時,若存在同時屬于DW_TAG_pointer_type 和DW_TAG_subroutine_type 的成員變量(即DW_TAG_member),該成員變量即為一個函數(shù)指針類型變量.更新結(jié)構(gòu)體變量時,只需對該變量的函數(shù)指針類型的成員變量進(jìn)行更新.當(dāng)聯(lián)合體中存在函數(shù)指針類型變量時,需要結(jié)合程序源代碼和匯編代碼分析定位所有使用其作為函數(shù)指針的指令及其所處的函數(shù)塊,只需在這些指令執(zhí)行時對聯(lián)合體變量的值進(jìn)行更新.

    隨機(jī)化變換后,首先根據(jù)函數(shù)指針類型變量的地址計算方式獲得其地址,然后由原值和函數(shù)布局信息表判斷出其要指向的目的函數(shù),最后由隨機(jī)化變換后該函數(shù)的新地址替換原值.

    (2)函數(shù)返回地址

    函數(shù)返回地址是被調(diào)用函數(shù)執(zhí)行完成后的后續(xù)指令的地址.隨機(jī)化變換后,返回地址也應(yīng)當(dāng)更新為變化后的新地址,以保證后續(xù)指令的正常執(zhí)行.返回地址保存在棧中,而且總是在前棧幀ebp 之前入棧.因此,EBP 寄存器中的值加上返回地址的長度,即為當(dāng)前函數(shù)的返回地址在棧中的位置.通過返回地址確定其對應(yīng)的指令所屬的函數(shù)塊以及該指令到函數(shù)入口的偏移值,然后根據(jù)該函數(shù)變換后的新地址加上偏移值,即得到了新的返回地址,最后將該值寫入到原返回地址所在的內(nèi)存單元中.之后,讀取出前棧幀ebp,并以該值為基礎(chǔ)更新下一個返回地址.循環(huán)上述過程,直到發(fā)現(xiàn)返回地址位于main 函數(shù)時停止.此時,目標(biāo)進(jìn)程的函數(shù)調(diào)用棧已遍歷完畢,所有的返回地址也已更新完成.

    (3)跳轉(zhuǎn)表

    若目標(biāo)程序中含有switch/case 語句,且當(dāng)case 語句較多時,C 編譯器會自動生成一個跳轉(zhuǎn)表(jump table)并存放在數(shù)據(jù)區(qū)中,通過該表進(jìn)行跳轉(zhuǎn),使switch/case 語句的執(zhí)行效率得到提高.跳轉(zhuǎn)表表項中存放的是case 語句的入口地址相對于.got.plt 的偏移offset.由于.got.plt 的地址在隨機(jī)化前后不變,而case 語句的入口地址將發(fā)生改變,因此當(dāng)目標(biāo)程序含有跳轉(zhuǎn)表時,表項(即offset 的值)必須進(jìn)行更新.首先定位到各個case 語句的入口地址;然后,基于該值和函數(shù)布局信息表判斷其所屬的函數(shù)塊以及該值和函數(shù)塊入口地址的偏移值;再根據(jù)該函數(shù)塊隨機(jī)化變換后的新地址加上該偏移值計算新的case 語句入口地址,并基于該值與.got.plt 的偏移得出offset 的值;最后,使用該值更新跳轉(zhuǎn)表的相應(yīng)表項.

    3.2 運(yùn)行時監(jiān)控

    代碼復(fù)用攻擊通常需經(jīng)過gadgets 獲取和利用兩個階段.由于ASLR 的廣泛應(yīng)用,通過直接或間接內(nèi)存泄漏獲取gadgets 信息已成為最有效的gadgets 獲取方式:直接內(nèi)存泄漏就是直接讀取(或掃描)程序代碼的內(nèi)存頁獲取gadgets;而間接內(nèi)存泄漏則通過代碼指針等數(shù)據(jù)(例如棧中的函數(shù)指針和返回地址等)推斷出可執(zhí)行代碼的內(nèi)存地址,不需要讀取代碼頁.LCR 分別采用讀后即變(change after reading,簡稱CAR)和用前即變(change before using,簡稱CBU)兩種機(jī)制,使攻擊者利用直接或間接內(nèi)存泄漏無法獲取到正確有效的gadgets 信息,從而無法實施代碼復(fù)用攻擊.

    3.2.1 CAR

    CAR 機(jī)制監(jiān)控攻擊者對目標(biāo)程序代碼所在內(nèi)存頁的讀數(shù)據(jù)操作,并觸發(fā)函數(shù)代碼塊內(nèi)存布局的隨機(jī)變換,使攻擊者通過直接內(nèi)存泄漏的方式無法獲得有效的代碼內(nèi)存分布信息.

    該種監(jiān)控通常有兩種實現(xiàn)方式.一是監(jiān)控系統(tǒng)中所有的讀操作,判斷其目的地址是否為目標(biāo)程序的代碼頁.該方式實現(xiàn)簡單,但開銷較大;二是將目標(biāo)程序的代碼頁設(shè)置為不可讀,當(dāng)讀這些內(nèi)存頁時導(dǎo)致訪問異常,通過異常處理實現(xiàn)監(jiān)控.該方式只監(jiān)控目標(biāo)內(nèi)存頁的讀操作,大大降低了監(jiān)控開銷復(fù)雜度.

    CAR 借助Intel VT 硬件虛擬化技術(shù)中提出的擴(kuò)展頁表技術(shù)(extended page-table,簡稱EPT)[11]實現(xiàn)了僅對目標(biāo)內(nèi)存頁讀操作的監(jiān)控.

    為保證目標(biāo)程序一開始執(zhí)行就得到保護(hù),CAR 通過監(jiān)控do_execve(·)內(nèi)核函數(shù)(kernel function,簡稱KF)(在Linux 操作系統(tǒng)中,該函數(shù)完成具體的程序加載工作)的執(zhí)行過程獲知目標(biāo)進(jìn)程是否已加載完成.這里給出監(jiān)控do_execve(·)等內(nèi)核函數(shù)的方法.通過分析發(fā)現(xiàn),編譯器會在每個函數(shù)塊入口插入如下兩條指令:“push %ebp;movl %esp,%ebp”,用于保存原ebp 并修改ebp 指針指向棧頂,且這兩條指令的長度與VMCALL 指令的長度相同(均為3 個字節(jié)).因此在系統(tǒng)運(yùn)行過程中,利用Hypervisor 將這些函數(shù)入口處的頭兩條指令替換成VMCALL即可使這些函數(shù)執(zhí)行時陷入Hypervisor,從而實現(xiàn)監(jiān)控.其中,內(nèi)核函數(shù)的入口地址可通過System.map 文件找到,最后,需在Hypervisor 中仿真執(zhí)行被覆蓋的兩條指令(“push %ebp;movl %esp,%ebp”)保證程序正常運(yùn)行.

    當(dāng)監(jiān)控到do_execve(·)函數(shù)陷入到Hypervisor 且由參數(shù)獲知加載對象為目標(biāo)程序時,保存棧中的返回地址,然后用一個非法的內(nèi)存地址(假設(shè)為Addr)替換該值.因此,當(dāng)do_execve(·)執(zhí)行完成返回時,將由于非法內(nèi)存訪問導(dǎo)致EPT violation 異常再次陷入Hypervisor.此時,標(biāo)志著目標(biāo)程序已加載完畢.

    目標(biāo)程序加載完畢后,立即將其代碼頁屬性設(shè)置為僅可執(zhí)行.首先,通過在Hypervisor 中重構(gòu)出目標(biāo)進(jìn)程的task_struct 結(jié)構(gòu)獲取start_code 和end_code 的值,從而得到其對應(yīng)的內(nèi)存頁;然后,清空并重新構(gòu)建EPT,此時將目標(biāo)進(jìn)程代碼所在內(nèi)存頁的屬性設(shè)置為僅可執(zhí)行;最后,將do_execve(·)的返回地址恢復(fù)為事先保存的正確值,保證程序仍能正常運(yùn)行.

    基于上述操作,目標(biāo)程序一旦加載運(yùn)行,其代碼頁即已被設(shè)置為僅可執(zhí)行.因此,當(dāng)執(zhí)行對這些代碼頁的讀操作時,將導(dǎo)致EPT Violation 異常而陷入Hypervisor.LCR 監(jiān)控到異常后,分析導(dǎo)致該異常的原因,若是由讀操作引起的,則修改要讀取的代碼頁屬性為可讀,并將虛擬機(jī)控制結(jié)構(gòu)(virtual machine control struct,簡稱VMCS)中的primary processor-based VM-execution control 字段的monitor trap flag 位設(shè)置為1(單步執(zhí)行),之后,執(zhí)行VMRESUME 返回客戶機(jī).當(dāng)客戶機(jī)執(zhí)行完讀操作指令后,將再次陷入到Hypervisor,此時將代碼頁的屬性恢復(fù)為僅可執(zhí)行,并同時觸發(fā)一次代碼隨機(jī)化操作(具體實現(xiàn)方法將在第3.3 節(jié)中闡述).

    CAR 不阻止對目標(biāo)進(jìn)程代碼的讀操作,但通過在每次讀操作后執(zhí)行一次隨機(jī)化,使攻擊者之前讀取到的內(nèi)存信息失效,能夠有效防御通過直接內(nèi)存泄漏實現(xiàn)的代碼復(fù)用攻擊.另外,由于假設(shè)攻擊者可獲得目標(biāo)程序的二進(jìn)制文件,因此攻擊者可在加載前獲取相關(guān)代碼信息,并在加載后直接進(jìn)行篡改和利用,而不需再讀取代碼.針對該情況,CAR 除了由程序加載之后的讀操作觸發(fā)隨機(jī)化外,還設(shè)定在程序加載完成后無條件觸發(fā)一次隨機(jī)化,使攻擊者通過二進(jìn)制文件獲得的信息失效.但由于CAR 機(jī)制只監(jiān)控讀代碼操作,無法防御間接內(nèi)存泄漏攻擊.

    CAR 是實時性的且在讀后立即實施,但該機(jī)制開銷并不高:首先,EPT 機(jī)制本身是基于硬件輔助實現(xiàn)的,因此基于該機(jī)制陷入陷出的效率遠(yuǎn)高于傳統(tǒng)的影子頁表技術(shù);另外,正常情況下,對代碼頁的訪問主要是取指操作,而將代碼頁設(shè)置為僅可執(zhí)行屬性時,取指操作并不會導(dǎo)致陷入,只有當(dāng)攻擊者試圖構(gòu)造攻擊時,才有可能大量產(chǎn)生由讀操作導(dǎo)致的陷入.上述分析與本文最后的性能測試結(jié)果也是一致的.

    3.2.2 CBU

    LCR 采用CBU 機(jī)制的目的是實現(xiàn)對間接內(nèi)存泄漏攻擊的防御.CBU 機(jī)制通過在攻擊者使用獲取的內(nèi)存信息發(fā)動攻擊前變換原有代碼內(nèi)存布局的方式,使攻擊者所利用的信息失效,導(dǎo)致攻擊失敗.

    TASR[12]首次提出攻擊實現(xiàn)的最小間隔理論,認(rèn)為執(zhí)行一個攻擊操作的最短間隔即最近的輸出操作和緊跟其后的輸入操作之間的時間長度.如果隨機(jī)化發(fā)生在每個最小間隔中間,攻擊者就失去了利用已知的內(nèi)存狀態(tài)信息實現(xiàn)攻擊的機(jī)會.但TASR 并沒有考慮那些不需要目標(biāo)進(jìn)程執(zhí)行輸出操作也能獲得內(nèi)存信息的攻擊方式,如內(nèi)存掃描方式,攻擊者只需通過執(zhí)行輸入操作即可實現(xiàn)攻擊.為了防御此類攻擊,CBU 機(jī)制采用更寬松的隨機(jī)化觸發(fā)機(jī)制,即每次目標(biāo)進(jìn)程執(zhí)行輸入類操作都將觸發(fā)一次隨機(jī)化處理.另外,TASR 未考慮那些本身就含有惡意邏輯,不需要輸入操作也可實現(xiàn)的來自惡意軟件自身的攻擊.而本文研究如何保護(hù)一個(非惡意的)軟件不受到外部攻擊,因此上述情況也不在本文考慮的范圍內(nèi).

    首先,通過對32 位linux 3.2.0-29 內(nèi)核的分析得到輸入類系統(tǒng)調(diào)用,并進(jìn)一步分析獲得每個系統(tǒng)調(diào)用實際執(zhí)行的關(guān)鍵內(nèi)核函數(shù),其結(jié)果見表2.通過對這些內(nèi)核函數(shù)的監(jiān)控,達(dá)到監(jiān)控輸入類操作的目的.實現(xiàn)方法已在第3.2.1 節(jié)中論述.

    當(dāng)檢測到上述內(nèi)核函數(shù)陷入后,還需要判斷該操作是否來自目標(biāo)進(jìn)程.為此,CBU 在監(jiān)控到目標(biāo)程序加載完成時(已在第3.2.1 節(jié)中論述)獲取該程序的基地址,即寄存器CR3 的值,并將該值作為判斷當(dāng)前進(jìn)程是否為目標(biāo)進(jìn)程的依據(jù).若當(dāng)前CR3 的值與目標(biāo)進(jìn)程的基地址值相同,則表明操作的發(fā)起者為目標(biāo)進(jìn)程,此時觸發(fā)對目標(biāo)進(jìn)程代碼的隨機(jī)化變換,否則不采取任何操作.

    CBU 機(jī)制在攻擊者使用獲取的內(nèi)存信息發(fā)動攻擊前變換原有代碼的內(nèi)存布局,使攻擊者所利用的信息失效,導(dǎo)致攻擊失敗.CBU 機(jī)制彌補(bǔ)了CAR 機(jī)制無法防御間接內(nèi)存泄漏的不足,而CAR 機(jī)制又對那些并不一定需要執(zhí)行輸入操作的代碼復(fù)用攻擊(例如JIT-ROP)提供了有效防御,兩種機(jī)制共同保證了LCR 防御代碼復(fù)用攻擊的能力.CBU 機(jī)制也是實時性的,它引入的性能開銷與目標(biāo)程序執(zhí)行的輸入操作的次數(shù)和頻率有關(guān),總體上比CAR 機(jī)制引入的開銷要大,尤其對于輸入密集型程序,如本文第4.2 節(jié)中測試的服務(wù)器程序nginx,當(dāng)對類似nginx 這類輸入密集型程序進(jìn)行保護(hù)時,可考慮在滿足一定安全性的基礎(chǔ)上關(guān)閉CBU 機(jī)制來換取較高的效率.

    Table 2 System calls that perform input operation表2 輸入類系統(tǒng)調(diào)用信息

    3.3 運(yùn)行時代碼隨機(jī)化

    3.3.1 代碼隨機(jī)化處理機(jī)制

    當(dāng)監(jiān)控到觸發(fā)事件時,Hypervisor 中的隨機(jī)化處理模塊負(fù)責(zé)完成對目標(biāo)進(jìn)程代碼段中函數(shù)塊布局的隨機(jī)化處理.首先,基于原始函數(shù)布局信息表對代碼中的函數(shù)進(jìn)行重排序,構(gòu)造新的函數(shù)布局信息表,并保證相鄰變換中任何函數(shù)塊都處于不同位置,見表1.LCR 采用的隨機(jī)化重排序算法如圖5 所示,其中,隨機(jī)數(shù)的產(chǎn)生依賴于Linux 內(nèi)核的隨機(jī)數(shù)發(fā)生器,該算法完成新函數(shù)布局表的生成、代碼內(nèi)存的變換以及相關(guān)內(nèi)容的更新.

    Fig.5 Code randomization reorder algorithm圖5 代碼隨機(jī)化重排序算法

    算法中的Max 是為了降低計算重排列的時間開銷而引入的.由于在進(jìn)行隨機(jī)化操作時需要對n個函數(shù)進(jìn)行全排列,并從中選擇某個排列來重新布局內(nèi)存,當(dāng)n較大時,全排列的開銷較大,而若先將n個函數(shù)劃分成Max個部分,再對Max 個部分進(jìn)行全排列則可將時間復(fù)雜度從O(n!)降低至O(Xax!).因此,Max 的引入對于提高算法性能、降低開銷具有重要意義.

    Max 在[2,n](n≥2)上取值,隨機(jī)化算法的開銷與Max 的值為正相關(guān)關(guān)系.另外,當(dāng)函數(shù)個數(shù)n一定時,Max 的值越小,就意味著平均每個分區(qū)中含有的函數(shù)數(shù)量越多,代碼長度越長.此時,雖然每次隨機(jī)化后代碼的絕對地址仍然都會發(fā)生變化,但相對地址未發(fā)生變化的代碼(即同一個分區(qū)內(nèi)的代碼)在所有代碼中所占的比重將越大,即一次隨機(jī)化變換后對原有內(nèi)存布局的打亂程度會越小,那么就可能降低攻擊者暴力破解的難度.所以在開銷可以容忍的情況下,Max 值越大越好(Max 最大等于n).但需要說明的是:Max 的大小并不影響LCR 方法對由直接或間接內(nèi)存泄露導(dǎo)致的代碼復(fù)用攻擊的防御能力,因為即使Max 取最小值2 時,也可實現(xiàn)對所有代碼內(nèi)存布局的隨機(jī)化變換,達(dá)到防御內(nèi)存泄露和代碼復(fù)用攻擊的效果.

    構(gòu)造新布局信息表后,按照該表對原代碼內(nèi)容進(jìn)行變換.首先,按照當(dāng)前函數(shù)布局信息表將目標(biāo)進(jìn)程代碼中的各個函數(shù)依次拷貝到另一塊臨時內(nèi)存區(qū)域.然后,再按照新函數(shù)布局信息表指定的各個函數(shù)的起始地址將臨時內(nèi)存區(qū)域中的函數(shù)寫回到目標(biāo)進(jìn)程內(nèi)存.由于進(jìn)程代碼頁正常情況下不可寫,為實現(xiàn)該操作,需將所在內(nèi)存頁的EPT 屬性修改為可寫.當(dāng)完成對所有函數(shù)塊的寫回后,根據(jù)新舊函數(shù)布局信息構(gòu)造一個映射f,實現(xiàn)從原內(nèi)存地址到新內(nèi)存地址的轉(zhuǎn)化.如圖6 所示,利用該映射對第3.1 節(jié)中提到的代碼段中的指令參數(shù)和相關(guān)數(shù)據(jù)的內(nèi)容進(jìn)行更新,然后恢復(fù)代碼頁的不可寫屬性,并修改RIP 寄存器,保證后續(xù)指令的正常執(zhí)行.此時,清空并刪除原函數(shù)布局信息表,而新函數(shù)布局信息表則作為下次變換的原始表.最后,由Hypervisor 陷出到客戶機(jī)繼續(xù)運(yùn)行目標(biāo)進(jìn)程.

    Fig.6 Mapping relationship between original and new memory layout圖6 新舊內(nèi)存布局之間的映射關(guān)系

    為了更有效地防御代碼復(fù)用攻擊,LCR 在隨機(jī)化操作時,除了.text 節(jié)外,還將.plt,.init 和.fini 節(jié)中的函數(shù)塊納入到隨機(jī)化的范疇,實現(xiàn)了對ELF 文件中所有可執(zhí)行部分的隨機(jī)化.其中,對.plt 段隨機(jī)化能有效防御returninto-libc 攻擊,而.init 和.fini 節(jié)是所有可執(zhí)行文件都具有的內(nèi)容,其中所含的gadgets 更容易被攻擊者利用.另外,為了不讓攻擊者發(fā)現(xiàn)函數(shù)布局信息表,該表始終存放在Hypervisor 中,且每次隨機(jī)化操作完成就徹底刪除原始函數(shù)布局信息表,只保留新函數(shù)布局表用于下次隨機(jī)化操作.

    3.3.2 安全性分析

    LCR 通過對原函數(shù)塊位置的變換,使攻擊者之前獲得的信息失效,無法以基于內(nèi)存泄漏的方式實現(xiàn)代碼復(fù)用攻擊.但攻擊者通過分析二進(jìn)制文件,仍有可能得到目標(biāo)程序的函數(shù)信息,若在此基礎(chǔ)上實施暴力破解攻擊,即枚舉函數(shù)塊變換后所有可能的布局方式,并分別發(fā)起攻擊,其成功的可能性還是存在的.假設(shè)目標(biāo)程序代碼中共含n個函數(shù)塊,攻擊者嘗試K次獲得成功.另外,假設(shè)當(dāng)嘗試失敗導(dǎo)致目標(biāo)進(jìn)程崩潰時,該程序?qū)⒆詣又貑?

    當(dāng)攻擊者不了解LCR 的隨機(jī)化機(jī)制(相鄰兩次排列各個元素的位置均不相同)時,需要嘗試每一種排序,則每一次成功的概率都是,那么此時K的期望值為

    即,攻擊者平均需要嘗試n!次才能成功.當(dāng)攻擊者了解LCR 的隨機(jī)化機(jī)制時,攻擊者只需要對那些與當(dāng)前排列相比元素的位置全部發(fā)生變化的排列進(jìn)行嘗試,最大化地縮小事件空間.此時,設(shè)滿足條件的新的排列總數(shù)為N,至少有一個元素在原來位置上的排列數(shù)為N′,則N=n!-N′.攻擊者只需在N個可能排列中進(jìn)行嘗試即可,其中,

    由上述分析可知:目標(biāo)程序的函數(shù)塊數(shù)目n越大,攻擊者實現(xiàn)暴力破解攻擊的難度越大.例如,當(dāng)n=10 時,E(K)1=3628800,E(K)2=1334961,而大部分應(yīng)用程序的函數(shù)塊數(shù)量遠(yuǎn)大于10.可見,LCR 方法的安全性是有理論保證的.另外,以上評估均在假設(shè)攻擊者嘗試失敗導(dǎo)致目標(biāo)進(jìn)程崩潰后進(jìn)程將自動重啟的條件下進(jìn)行,但在實際應(yīng)用中,可通過相關(guān)設(shè)置阻止進(jìn)程自動重啟,還可通過對程序異常崩潰情況的分析檢測攻擊,從而進(jìn)一步提高目標(biāo)程序防御代碼復(fù)用攻擊的能力.在這種情況下,攻擊者攻擊成功的可能性將更低.

    4 方法評估

    在32 位Ubuntu12.04 系統(tǒng)上對LCR 進(jìn)行了實現(xiàn).系統(tǒng)內(nèi)核版本為3.2.0-29-generic-pae,其中,物理地址擴(kuò)展機(jī)制(physical address extension,簡稱PAE)默認(rèn)開啟,gcc 版本為4.6.3,而Hypervisor 是基于Intel VT 技術(shù)設(shè)計的一個輕量級的虛擬機(jī)監(jiān)控器,該監(jiān)控器除對無條件陷入事件[11]進(jìn)行處理外,只對LCR 中涉及到的觸發(fā)事件進(jìn)行監(jiān)控,目的是最大化地降低監(jiān)控開銷.計算系統(tǒng)采用4 核Intel 處理器(CoreTMi7-3770,主頻3.40GHz)和16GB 內(nèi)存(RAM).

    4.1 有效性測試

    4.1.1 隨機(jī)化有效性測試

    本次測試中通過對比隨機(jī)化前后內(nèi)存布局的變化來驗證LCR 隨機(jī)化處理的有效性.

    為了更具體地體現(xiàn)LCR 隨機(jī)化處理過程,以程序exam 為例進(jìn)行了測試:首先,利用ROPgedget[15]分析exam的二進(jìn)制文件獲得gadgets 的信息列表,如圖7 所示,其中,每個gadget 對應(yīng)的16 進(jìn)制編碼也已在圖中列出;然后,在未實施LCR 保護(hù)的情況下運(yùn)行exam,并假設(shè)攻擊者可通過一定方式得到exam 本次加載的虛擬地址0xb770e000(攻擊者可通過hook 系統(tǒng)的程序加載過程、提取目標(biāo)程序的task_struct 結(jié)構(gòu)等方式獲得該信息),并通過地址轉(zhuǎn)換獲得了其對應(yīng)的物理地址0x3dbfdf000.測試中,由Hypervisor 提取出exam 可執(zhí)行代碼對應(yīng)的內(nèi)存內(nèi)容(0x3dbfdf438~0x3dbfdf751,對應(yīng)_init,.plt,.text 和.fini 這4 個節(jié)),如圖8(a)所示.可見,此時攻擊者可以利用圖7 中獲得的地址信息從exam 的內(nèi)存空間中成功定位到gadgets.

    Fig.7 Running results of ROPgadgets圖7 ROPgadgets 的運(yùn)行結(jié)果

    Fig.8 Memory of executable code in exam圖8 exam 中可執(zhí)行代碼對應(yīng)的內(nèi)存內(nèi)容

    之后,利用LCR 對exam 實施保護(hù),由Hypervisor 在每次隨機(jī)化處理完成時讀取一次exam 進(jìn)程的可執(zhí)行代碼對應(yīng)的內(nèi)存內(nèi)容,某一次讀取的結(jié)果如圖8(b)所示.為了更好地對比隨機(jī)化效果,在測試中同時保留了原始函數(shù)布局信息表和新函數(shù)布局信息表,通過對比發(fā)現(xiàn),本次隨機(jī)化操作實現(xiàn)了 0x3dbfdf438~0x3dbfdf67f 和0x3dbfdf680~0x3dbfdf751 兩部分內(nèi)容的位置互換.此時,當(dāng)攻擊者再次按照之前獲取的gadgets 地址信息去讀取內(nèi)存內(nèi)容時,已無法得到有效的gadgets.說明隨機(jī)化處理后原有信息失效.

    為使結(jié)果更具有代表性,按照上述方法對SPEC CPU2006 中用C 語言實現(xiàn)的基準(zhǔn)程序進(jìn)行了測試(400.perlbench 除外,因存在運(yùn)行時翻譯代碼,編譯時無法直接獲得完整的代碼信息),在編譯時使用-pie 和-gdwarf-4選項生成可執(zhí)行代碼.測試中,首先利用ROPgadget 提取各基準(zhǔn)程序中含有的gadgets 信息,然后分別在采用和未采用LCR 保護(hù)的情況下運(yùn)行基準(zhǔn)程序,并在運(yùn)行過程中獲取可執(zhí)行代碼的內(nèi)存快照,據(jù)此分析隨機(jī)化變換前后gadgets 的變化情況.當(dāng)采用LCR 保護(hù)時,為測試LCR 的動態(tài)隨機(jī)化效果,測試中隨機(jī)選擇3 個時間點獲取內(nèi)存快照進(jìn)行分析,3 個時間點獲得的內(nèi)存快照中均沒有定位到任何可用的gadgets.測試結(jié)果見表3.

    Table 3 Validity tests of the randomization表3 隨機(jī)化有效性測試

    通過上述測試表明:LCR 能夠有效實現(xiàn)對目標(biāo)進(jìn)程內(nèi)存空間中的可執(zhí)行代碼區(qū)域的隨機(jī)化變換,攻擊者通過靜態(tài)分析和內(nèi)存泄漏等方式無法獲取有效的gadgets 信息.

    4.1.2 代碼復(fù)用攻擊防御能力測試

    為測試LCR 對代碼復(fù)用攻擊的防御能力,首先編寫了含有棧緩沖區(qū)溢出漏洞的目標(biāo)程序targetProc,然后借助ROPgadget 構(gòu)造針對targetProc 的ROP 攻擊payload,用于生成新的shell.在targetProc 程序運(yùn)行過程中,通過輸入操作將該ROP 攻擊的payload 注入到targetProc 的棧中,并篡改控制流使payload 得到執(zhí)行.分別在采用和未采用LCR 保護(hù)的情況下進(jìn)行上述測試,結(jié)果見表4.當(dāng)采用LCR 保護(hù)時,ROP 攻擊失敗,因為當(dāng)LCR 對該程序的可執(zhí)行代碼進(jìn)行隨機(jī)化后,注入的payload 中所使用的gadgets 地址信息已失效,因而此時仍然利用這些失效的地址串聯(lián)執(zhí)行最終導(dǎo)致程序崩潰,無法實現(xiàn)攻擊目標(biāo).

    Table 4 Tests results of the ROP attack表4 ROP 攻擊測試結(jié)果

    另外,分析和總結(jié)了當(dāng)前已知的各類代碼復(fù)用攻擊技術(shù).由于無法獲得它們的實現(xiàn)代碼,因此通過對它們實現(xiàn)機(jī)制的分析來判斷LCR 能否防御這些攻擊,分析結(jié)果見表5.上述分析都在滿足本文的攻擊模型和假設(shè)條件下進(jìn)行.

    Table 5 Analysis LCR ability to defend CRAs表5 LCR 代碼復(fù)用攻擊防御能力分析

    4.2 性能測試

    LCR 基于虛擬機(jī)監(jiān)控器實現(xiàn),不僅會對被保護(hù)的目標(biāo)程序產(chǎn)生影響,也會對整個系統(tǒng)的性能產(chǎn)生影響.因此,為了充分說明LCR 帶來的各類性能開銷,分別在裸機(jī)、Hypervisor、Hypervisor 下開啟內(nèi)核函數(shù)監(jiān)控和Hypervisor 下開啟LCR(其中,隨機(jī)化重排序算法中的Max 設(shè)置為10)這4 種環(huán)境下進(jìn)行了測試,所有測試均使用表4 中列出的SPEC CPU2006 中的C 語言基準(zhǔn)測試程序,并且使用-pie 和-gdwarf-4 編譯選項.

    根據(jù)圖9 所示的測試結(jié)果可知,本文設(shè)計的輕量級虛擬機(jī)監(jiān)控器Hypervisor 在不監(jiān)控內(nèi)核函數(shù)時開銷很小.這是因為借助Intel VT,只需處理無條件陷入事件(該類事件執(zhí)行頻率很低),對不需要陷入的其他操作都采用直接穿透的方式由客戶機(jī)操作系統(tǒng)負(fù)責(zé)完成.開啟內(nèi)核函數(shù)監(jiān)控后,當(dāng)執(zhí)行表2 中的7 類關(guān)鍵內(nèi)核函數(shù)時會發(fā)生陷入,開銷稍有增加,但由于只在陷入后模擬執(zhí)行“push %ebp;movl %esp,%ebp”兩條指令,引入的開銷仍然很小.啟動LCR 后,由于要在每次觸發(fā)事件發(fā)生時對目標(biāo)程序代碼的內(nèi)存進(jìn)行隨機(jī)化變換,在一次變換中,每一頁都要經(jīng)過兩次讀寫操作,從而引入了較多運(yùn)行開銷,與未開啟Hypervisor 時相比,最小和最大開銷分別為0.22%(433.milc)和18.23%(456.hmmer),而平均開銷為4.89%.可見,LCR 雖然引入了部分開銷,但仍滿足實用性要求[22].

    為了更深入地分析LCR 的性能開銷,測試中統(tǒng)計了每個基準(zhǔn)程序運(yùn)行過程中監(jiān)控到的內(nèi)核函數(shù)的執(zhí)行次數(shù)和觸發(fā)CBU 的次數(shù),以及各基準(zhǔn)程序可執(zhí)行代碼對應(yīng)的內(nèi)存區(qū)的總頁數(shù)(start_code~end_code)和有效頁的總頁數(shù)(非零頁).表中每個數(shù)據(jù)的分母表示監(jiān)控到的執(zhí)行總數(shù),而分子表示來自于基準(zhǔn)程序的執(zhí)行次數(shù),即觸發(fā)CBU 的次數(shù).由于測試中未監(jiān)控到vfs_readv,do_msgrcv,__sys_recvmsg 和__audit_mq_sendrecv 這4 個內(nèi)核函數(shù)的執(zhí)行,因此未予未列出.統(tǒng)計結(jié)果見表6.

    Fig.9 Running overhead for SPEC CPU2006 under four different conditions圖9 SPEC CPU2006 在4 種不同條件下的運(yùn)行開銷

    Table 6 Statistics and analysis of the test data表6 測試數(shù)據(jù)的統(tǒng)計分析

    由表6 可知,433.milc 開銷小是由于其觸發(fā)的CBU 次數(shù)少,且每次隨機(jī)化處理的內(nèi)存頁也很少.目標(biāo)程序的開銷與隨機(jī)化過程中處理的總內(nèi)存頁數(shù)(即CBU 觸發(fā)次數(shù)和有效頁的乘積,忽略加載時的一次隨機(jī)化)的關(guān)系如圖10 所示,兩者基本呈正比關(guān)系,即:當(dāng)目標(biāo)程序執(zhí)行過程中含有越多的輸入操作且可執(zhí)行代碼量越大時,該程序采用LCR 保護(hù)后的開銷也會越大.實際測試結(jié)果中存在個別不符合正比關(guān)系的情況,是因為每個程序運(yùn)行過程中系統(tǒng)執(zhí)行關(guān)鍵內(nèi)核函數(shù)的總數(shù)具有一定偶然性,當(dāng)該數(shù)量較大時,也會對程序的運(yùn)行開銷產(chǎn)生一定影響.

    Fig.10 Relationship between running overhead and total pages which need to be handled圖10 運(yùn)行開銷和處理的總頁數(shù)之間的關(guān)系

    由于LCR 的CBU 機(jī)制在輸入類操作時觸發(fā)代碼隨機(jī)化,因此,為評估LCR 對高I/O 程序的性能影響,采用webbench-1.5[23]對nginx 服務(wù)器程序在不同環(huán)境下的處理能力進(jìn)行了測試.測試命令為webbench-c 100-t 30 http://127.0.0.1/,即并發(fā)數(shù)為100,時間為30s,測試結(jié)果如圖11 所示.在開啟對所有輸入類操作的監(jiān)控后(即KF monitor 環(huán)境下),nginx 處理能力明顯下降;而開啟CAR 和CBU 之后(即LCR(CAR&CBU)環(huán)境下),nginx 處理能力下降64.3%.測試發(fā)現(xiàn):nginx 在測試的30s 中,約產(chǎn)生了12 次vfs_read 操作和高達(dá)9 363 次sock_recvmsg 操作,共觸發(fā)約9 375 次隨機(jī)化操作.正是短時間內(nèi)集中觸發(fā)的大量隨機(jī)化操作,使nginx 處理能力下降.

    Fig.11 Processing capacity of nginx under five different conditions圖11 nginx 在5 種環(huán)境下的處理能力

    nginx 不僅是一種高I/O 程序,而且在工作時通常會出現(xiàn)I/O 密集型操作,即,在短時間內(nèi)執(zhí)行大量輸入/輸出操作,因此,使用LCR 對該類程序進(jìn)行保護(hù)時開銷會較大.在對性能要求較高的場合,存在兩種可行的方案來降低LCR 的開銷.一種是通過僅對這類程序采取CAR 保護(hù)機(jī)制,如圖11 中的LCR(CAR only)所示,此時性能開銷很小(約為1.07%).這種通過犧牲部分安全性來換取高性能的做法也是安全領(lǐng)域經(jīng)常采用的平衡策略.另外,由于目前大部分的代碼復(fù)用攻擊仍借助直接內(nèi)存泄漏實現(xiàn),因此,僅開啟CAR 機(jī)制仍能顯著提高對代碼復(fù)用攻擊的防御能力;另一種是采取CAR 和周期性隨機(jī)化相結(jié)合的方式,這樣既能降低部分開銷,又能保證對間接內(nèi)存泄漏攻擊具有一定的防御能力.

    5 LCR 的局限性

    LCR 的局限性主要體現(xiàn)在以下幾個方面.

    (1)LCR 目前僅支持C 語言程序.首先,C 程序是一種廣泛使用的非類型安全語言,且存在較多內(nèi)存破壞漏洞,對這類程序的安全防護(hù)非常具有現(xiàn)實意義;其次,C 語言中的函數(shù)指針無法通過其他數(shù)據(jù)類型轉(zhuǎn)換得到,使對函數(shù)指針類型變量的跟蹤和更新成為可能.本文提出的動態(tài)隨機(jī)化代碼復(fù)用攻擊防御思想也可用于其他語言程序,只需解決對需要更新的函數(shù)指針等相關(guān)數(shù)據(jù)的定位和跟蹤即可,涉及程序分析技術(shù)和程序動態(tài)跟蹤技術(shù)的相關(guān)研究.由于本文重點在于提出和驗證這樣一種動態(tài)隨機(jī)化的防御思想,并未研究對所有語言類型的支持;

    (2)LCR 是以函數(shù)塊而非gadgets 為對象進(jìn)行隨機(jī)化,因此可能存在以下情況,即:函數(shù)塊位置變了,但gadgets 仍在原位置.例如,變換后,原函數(shù)func1 的ret 指令處變成了func2 的ret 指令.由于LCR 隨機(jī)化變換前后代碼所在的內(nèi)存空間不變,出現(xiàn)該類情況需滿足以下條件:首先,不同函數(shù)中必須含有相同的gadgets;另外,還要保證被該gadgets 所在的新函數(shù)塊分成兩部分的原內(nèi)存空間,每一部分都正好可以容下剩下的若干函數(shù)塊.當(dāng)含相同gadgets 的兩個函數(shù)塊大小一致時,該情況出現(xiàn)的可能性較大;而當(dāng)兩者大小不一致時,則可能性很小.為應(yīng)對這類情況,可通過在隨機(jī)化變換時增加對原gadgets 地址處的內(nèi)容審查,若發(fā)現(xiàn)內(nèi)容一致,則再觸發(fā)一次隨機(jī)化.研究發(fā)現(xiàn),大多數(shù)代碼復(fù)用攻擊往往由多個gadgets 配合實現(xiàn).因此,除非使用的所有g(shù)adgets 在隨機(jī)化后都仍在原位置(概率很小),否則攻擊仍會失敗.為兼顧安全和效率,LCR 暫未對該類情況進(jìn)行處理;

    (3)對于多線程程序,攻擊者可能通過對子進(jìn)程的分析獲得相關(guān)的內(nèi)存信息實現(xiàn)代碼復(fù)用攻擊.文獻(xiàn)[24]已經(jīng)對該類情況進(jìn)行了詳細(xì)分析,并通過在fork 時再次隨機(jī)化每個子進(jìn)程的地址空間,實現(xiàn)了對該類攻擊的防御.LCR 借助該方法實現(xiàn)對多線程目標(biāo)程序的代碼復(fù)用攻擊防御;

    (4)LCR 僅對目標(biāo)程序自身代碼而未對動態(tài)鏈接庫的代碼進(jìn)行隨機(jī)化,因此,LCR 無法防御那些不依賴讀程序代碼或者.plt 來獲取動態(tài)鏈接庫內(nèi)存地址,且僅利用動態(tài)鏈接庫代碼實現(xiàn)的代碼復(fù)用攻擊.此類攻擊可通過代碼掃描(掃描動態(tài)鏈接庫代碼而非目標(biāo)程序代碼)或旁信道攻擊[25]等方式來獲取所需要的動態(tài)鏈接庫代碼地址.基于程序控制流的監(jiān)控對該類攻擊具有較好的防御效果,也是我們下一步要研究的重要內(nèi)容.

    6 相關(guān)工作

    (1)代碼隨機(jī)化防御方法

    該類方法的核心思想是:增加獲取gadgets 的難度,使攻擊者無法獲得足夠多且有效的gadgets 來構(gòu)造攻擊.ASLR[2]最早提出了一種對動態(tài)鏈接庫和可執(zhí)行文件的加載地址隨機(jī)化的方法,使攻擊者無法定位gadgets,但攻擊者只需發(fā)現(xiàn)一個指令的地址即可獲得其他所有指令的地址.為提高ASLR 的安全性,更細(xì)粒度的隨機(jī)化方法不斷被提出,包括指令級隨機(jī)化[5]、基本塊隨機(jī)化[6]、函數(shù)隨機(jī)化[7]以及頁面級的隨機(jī)化[8].但上述方法都只在加載時執(zhí)行一次隨機(jī)化,攻擊者仍可通過內(nèi)存泄漏定位到gadgets.與該類方法相比,LCR 采用動態(tài)運(yùn)行時多次隨機(jī)化,能夠使攻擊者通過直接或間接內(nèi)存泄漏獲得的信息失效,在能防御的內(nèi)存泄露攻擊類型和代碼復(fù)用攻擊的防御能力方面都得到顯著提高.

    JIT-ROP 攻擊在程序運(yùn)行過程中尋找gadgets 加以利用,這使所有的加載時隨機(jī)化方法失效.為了應(yīng)對這類新型攻擊,動態(tài)隨機(jī)化方法被提出,LCR 就屬于該類方法.Isomeron[13]同時運(yùn)行程序的兩個不同副本,使攻擊者無法確定哪一個gadget 會得到執(zhí)行,即Isomeron 僅提供兩種可能的變換,而LCR 是在第3.3.2 節(jié)中分析的N=n!-N′種可能性中選擇一種進(jìn)行代碼的隨機(jī)化.因此,相比于Isomeron,LCR 的隨機(jī)化熵值得到顯著提高.文獻(xiàn)[26]首次提出操作系統(tǒng)的動態(tài)隨機(jī)化方法,但該方法采用周期性隨機(jī)化,存在攻擊窗口且實用性較差.Remix[27]動態(tài)隨機(jī)變換程序每個函數(shù)體內(nèi)基本塊的順序,但函數(shù)塊本身位置不變,不能防御函數(shù)級復(fù)用攻擊.文獻(xiàn)[24]提出了一種通過在fork 之后再次隨機(jī)化子進(jìn)程內(nèi)存空間防御clone-probing 攻擊的方法,但該方法不能防御直接內(nèi)存泄漏攻擊.TASR[12]采用最短攻擊間隔觸發(fā)隨機(jī)化,實現(xiàn)了對程序整個代碼段內(nèi)存位置的動態(tài)變化,但整個代碼段內(nèi)容不變,因此,一旦攻擊者通過某種機(jī)制定位到該程序的內(nèi)存,即可掌握其所有代碼特征,無法防御只需一次或不需要輸入操作的攻擊(如JIT-ROP 攻擊);另外,TASR 的隨機(jī)化模塊位于用戶層,易被破壞,安全性較低.相比上述動態(tài)隨機(jī)化方法,LCR 首次提出了以CAR 和CBU 相結(jié)合的函數(shù)級動態(tài)隨機(jī)化方法防御代碼復(fù)用攻擊,所能防御的代碼復(fù)用攻擊類型更多(TASR 無法防御只需一次或不需要輸入操作的攻擊;Remix 不能防御函數(shù)級復(fù)用攻擊,文獻(xiàn)[24]無法防御直接內(nèi)存泄露攻擊,文獻(xiàn)[26]存在攻擊窗口),能夠提供更高的安全性.

    (2)控制流完整性保護(hù)方法

    該類研究的目的是阻止攻擊者篡改控制流,使gadgets 序列得不到執(zhí)行.CFI 是由Abadi 等人.最早提出的[28],旨在基于控制流圖(control-flow graph,簡稱CFG)防御所有控制流劫持攻擊.但該方法開銷較大,實用性差.因此,目前最新的研究仍集中在如何提高該方法的實用性上.CCFIR[29],CCFI[30],PICFI[31],Context-sensitive CFI[32]和文獻(xiàn)[33]等結(jié)合對程序語義的分析,降低對CFG 精確度的要求,以達(dá)到降低監(jiān)控開銷的目的.但研究者已證明:即使細(xì)粒度的CFI 類保護(hù)方法,也無法真正保證控制流的安全[34],控制流被劫持的風(fēng)險依然存在.

    (3)其他防御方法

    除了上述兩類方法外,還有在編譯時減少可構(gòu)建gadgets 的指令的方法,例如G-free[35],但這類防御方法可防御的代碼復(fù)用攻擊類型有限;還有通過拒絕對代碼的讀操作[36]防御直接內(nèi)存泄漏的方法,但無法防御間接內(nèi)存泄漏;以及通過保護(hù)代碼指針的安全性防御代碼復(fù)用攻擊的方法CPI[37],但該方法已被證明是可以被繞過的[38].另外,還有通過代碼和數(shù)據(jù)隔離的方法[10,39],可防御內(nèi)存泄漏攻擊,但實際的函數(shù)代碼不變,可能遭到return-intolibc 攻擊.而LCR 則可以有效阻止直接和間接內(nèi)存泄漏攻擊以及return-into-libc 攻擊.

    7 總結(jié)

    本文提出了一種運(yùn)行時代碼隨機(jī)化防御代碼復(fù)用攻擊的方法LCR,并分別對預(yù)處理階段、動態(tài)監(jiān)控階段和隨機(jī)化處理階段進(jìn)行了詳細(xì)論述.LCR 采用CAR 和CBU 兩種機(jī)制,分別實現(xiàn)在攻擊者獲取gadgets 信息后和利用gadgets 前對目標(biāo)進(jìn)程代碼中函數(shù)塊的隨機(jī)化變換,使攻擊者通過直接或間接內(nèi)存泄漏獲得的gadgets 信息失效,從而阻止代碼復(fù)用攻擊的實現(xiàn).對LCR 原型系統(tǒng)的測試表明:該方法能夠有效實現(xiàn)在目標(biāo)程序運(yùn)行過程中對其代碼內(nèi)容的隨機(jī)化變換,可防御大部分已知代碼復(fù)用攻擊,并且平均開銷低于5%,具有良好的實用性.

    猜你喜歡
    攻擊者內(nèi)存代碼
    基于微分博弈的追逃問題最優(yōu)策略設(shè)計
    “春夏秋冬”的內(nèi)存
    創(chuàng)世代碼
    動漫星空(2018年11期)2018-10-26 02:24:02
    創(chuàng)世代碼
    動漫星空(2018年2期)2018-10-26 02:11:00
    創(chuàng)世代碼
    動漫星空(2018年9期)2018-10-26 01:16:48
    創(chuàng)世代碼
    動漫星空(2018年5期)2018-10-26 01:15:02
    正面迎接批判
    愛你(2018年16期)2018-06-21 03:28:44
    有限次重復(fù)博弈下的網(wǎng)絡(luò)攻擊行為研究
    基于內(nèi)存的地理信息訪問技術(shù)
    上網(wǎng)本為什么只有1GB?
    国产成人免费观看mmmm| 国产精品人妻久久久影院| 亚洲av.av天堂| 天美传媒精品一区二区| 非洲黑人性xxxx精品又粗又长| 在线播放国产精品三级| 亚洲在久久综合| 日韩精品青青久久久久久| 爱豆传媒免费全集在线观看| 欧美一区二区亚洲| 人妻系列 视频| 可以在线观看毛片的网站| 网址你懂的国产日韩在线| 国产三级在线视频| 淫秽高清视频在线观看| 免费黄色在线免费观看| 波多野结衣巨乳人妻| 精品不卡国产一区二区三区| 最新中文字幕久久久久| 狠狠狠狠99中文字幕| 国产精品一二三区在线看| 美女被艹到高潮喷水动态| 亚洲国产高清在线一区二区三| 免费播放大片免费观看视频在线观看 | 插逼视频在线观看| 久久99热这里只有精品18| 欧美激情在线99| 欧美3d第一页| 亚洲成av人片在线播放无| 中文字幕av成人在线电影| 国产精品,欧美在线| 18禁在线无遮挡免费观看视频| 色视频www国产| 国产午夜精品一二区理论片| 22中文网久久字幕| 午夜久久久久精精品| 日本熟妇午夜| 久久精品国产自在天天线| 日韩成人av中文字幕在线观看| 久久久久性生活片| 亚洲在久久综合| 国产一区二区三区av在线| 成人漫画全彩无遮挡| 最近的中文字幕免费完整| 99热精品在线国产| 纵有疾风起免费观看全集完整版 | a级毛片免费高清观看在线播放| 久久久国产成人免费| 亚洲人成网站高清观看| 男的添女的下面高潮视频| 国产国拍精品亚洲av在线观看| 男人和女人高潮做爰伦理| 观看免费一级毛片| 国产精品综合久久久久久久免费| 国产av不卡久久| 1024手机看黄色片| 国产精品电影一区二区三区| 我的老师免费观看完整版| 国产成年人精品一区二区| 久久久久九九精品影院| 成人综合一区亚洲| 22中文网久久字幕| av在线天堂中文字幕| 国产视频内射| 国产精品一区二区三区四区免费观看| 久久久成人免费电影| 好男人视频免费观看在线| 成人毛片a级毛片在线播放| 国产精品人妻久久久久久| 桃色一区二区三区在线观看| 国产真实乱freesex| 男人狂女人下面高潮的视频| 亚洲av不卡在线观看| 晚上一个人看的免费电影| 晚上一个人看的免费电影| 成人美女网站在线观看视频| 在线播放无遮挡| .国产精品久久| 成年女人看的毛片在线观看| 我的老师免费观看完整版| 亚洲自拍偷在线| 国产精品一及| 中文字幕熟女人妻在线| 丰满少妇做爰视频| 国产美女午夜福利| 成人亚洲精品av一区二区| 18+在线观看网站| 汤姆久久久久久久影院中文字幕 | 国产成年人精品一区二区| 日韩亚洲欧美综合| 中国美白少妇内射xxxbb| 亚洲乱码一区二区免费版| 观看美女的网站| 国产精品久久久久久久久免| 黄色配什么色好看| 亚洲综合色惰| 日韩 亚洲 欧美在线| 少妇的逼水好多| 日本五十路高清| 一级毛片久久久久久久久女| 晚上一个人看的免费电影| h日本视频在线播放| 久久久久精品久久久久真实原创| 能在线免费看毛片的网站| 十八禁国产超污无遮挡网站| 寂寞人妻少妇视频99o| 天堂√8在线中文| 在线免费观看不下载黄p国产| 久久亚洲国产成人精品v| 亚洲欧美日韩无卡精品| 一本久久精品| 国产欧美日韩精品一区二区| 神马国产精品三级电影在线观看| 一级二级三级毛片免费看| 免费看av在线观看网站| 天堂av国产一区二区熟女人妻| 欧美三级亚洲精品| АⅤ资源中文在线天堂| 久久草成人影院| 国产亚洲精品av在线| 亚洲成人av在线免费| 99久久中文字幕三级久久日本| 男女国产视频网站| 国产一级毛片在线| 在线天堂最新版资源| 国产成人精品婷婷| 韩国高清视频一区二区三区| 国产探花极品一区二区| 亚洲怡红院男人天堂| 春色校园在线视频观看| 久久久欧美国产精品| 欧美日韩在线观看h| 91精品伊人久久大香线蕉| 国产亚洲av片在线观看秒播厂 | 亚洲精品,欧美精品| av视频在线观看入口| 日本三级黄在线观看| 国产精品久久久久久久电影| 变态另类丝袜制服| 99久国产av精品| 黄色日韩在线| 亚洲av福利一区| 少妇人妻精品综合一区二区| 搞女人的毛片| 美女国产视频在线观看| 久久精品夜色国产| 精品不卡国产一区二区三区| 长腿黑丝高跟| 成人鲁丝片一二三区免费| 三级经典国产精品| 久久久久久国产a免费观看| 超碰97精品在线观看| 岛国毛片在线播放| 变态另类丝袜制服| 午夜精品国产一区二区电影 | 国产成人a区在线观看| 日韩一本色道免费dvd| 日本免费a在线| 色尼玛亚洲综合影院| 午夜福利网站1000一区二区三区| 久久综合国产亚洲精品| 又爽又黄a免费视频| 如何舔出高潮| www.av在线官网国产| 久久久久久久久久黄片| 亚洲欧美一区二区三区国产| 成人高潮视频无遮挡免费网站| 国产成人91sexporn| 国产精品久久久久久精品电影小说 | 婷婷六月久久综合丁香| 麻豆成人午夜福利视频| 久久久久久久久久成人| 高清av免费在线| 男人狂女人下面高潮的视频| 全区人妻精品视频| 狂野欧美激情性xxxx在线观看| 欧美成人精品欧美一级黄| 人体艺术视频欧美日本| 亚洲av一区综合| 久久精品国产鲁丝片午夜精品| 中文天堂在线官网| 嫩草影院入口| 中国美白少妇内射xxxbb| 久久这里只有精品中国| 国产黄色视频一区二区在线观看 | 欧美成人a在线观看| 日韩视频在线欧美| 国内揄拍国产精品人妻在线| 日本欧美国产在线视频| 黄色配什么色好看| 久久久精品欧美日韩精品| 欧美另类亚洲清纯唯美| 欧美又色又爽又黄视频| 国语对白做爰xxxⅹ性视频网站| 国产伦精品一区二区三区四那| 美女大奶头视频| 美女cb高潮喷水在线观看| 国产午夜精品一二区理论片| 婷婷六月久久综合丁香| 国产精品美女特级片免费视频播放器| av福利片在线观看| a级毛片免费高清观看在线播放| 国产精品蜜桃在线观看| 国产爱豆传媒在线观看| 国语对白做爰xxxⅹ性视频网站| 18+在线观看网站| 日韩制服骚丝袜av| 非洲黑人性xxxx精品又粗又长| 亚洲经典国产精华液单| 日本免费a在线| 99热这里只有是精品50| 亚洲美女视频黄频| 一级av片app| 欧美三级亚洲精品| av卡一久久| 欧美变态另类bdsm刘玥| 久久久久久久久久黄片| 欧美高清性xxxxhd video| 日韩欧美 国产精品| 狠狠狠狠99中文字幕| 亚洲三级黄色毛片| 亚洲怡红院男人天堂| 秋霞在线观看毛片| 99视频精品全部免费 在线| 国产精品精品国产色婷婷| 久久久a久久爽久久v久久| 欧美日本亚洲视频在线播放| 一级毛片我不卡| 在线播放无遮挡| 最近最新中文字幕免费大全7| 青春草国产在线视频| 国产熟女欧美一区二区| 两个人视频免费观看高清| 夜夜爽夜夜爽视频| 99热网站在线观看| 久久久久久久国产电影| 亚洲乱码一区二区免费版| 亚洲四区av| 亚洲欧美日韩东京热| 色哟哟·www| 高清毛片免费看| 日日啪夜夜撸| 久久久国产成人免费| 女人久久www免费人成看片 | 欧美不卡视频在线免费观看| 一级毛片电影观看 | 少妇人妻一区二区三区视频| 国产精品熟女久久久久浪| 国内精品一区二区在线观看| 亚洲av成人av| 国产大屁股一区二区在线视频| 久久99蜜桃精品久久| 亚洲四区av| 伦理电影大哥的女人| 国国产精品蜜臀av免费| 国产综合懂色| 草草在线视频免费看| 99热全是精品| 日韩av不卡免费在线播放| 成人无遮挡网站| 高清视频免费观看一区二区 | 国产精品熟女久久久久浪| 日本熟妇午夜| 成人国产麻豆网| 99久国产av精品国产电影| 麻豆成人av视频| 少妇人妻一区二区三区视频| 亚洲欧美清纯卡通| 亚洲av二区三区四区| 成人漫画全彩无遮挡| 成人综合一区亚洲| 亚洲一级一片aⅴ在线观看| 如何舔出高潮| 亚洲精品,欧美精品| 日韩亚洲欧美综合| 精品熟女少妇av免费看| 能在线免费看毛片的网站| 日韩国内少妇激情av| 成人特级av手机在线观看| 国产日韩欧美在线精品| 亚洲av男天堂| 亚洲国产精品久久男人天堂| 日本与韩国留学比较| 老司机影院成人| 国产精品一区二区在线观看99 | 性插视频无遮挡在线免费观看| 国产午夜精品论理片| 国产成人福利小说| 欧美97在线视频| 国产精品久久久久久精品电影| 国产精品伦人一区二区| 免费看a级黄色片| 国产老妇伦熟女老妇高清| 国产精品1区2区在线观看.| 视频中文字幕在线观看| 亚洲国产日韩欧美精品在线观看| 国产成人福利小说| 一级毛片aaaaaa免费看小| 亚洲伊人久久精品综合 | 男人舔奶头视频| 国产老妇伦熟女老妇高清| 99视频精品全部免费 在线| 一二三四中文在线观看免费高清| 中国美白少妇内射xxxbb| 精品久久国产蜜桃| 国产伦精品一区二区三区四那| 一本—道久久a久久精品蜜桃钙片 精品乱码久久久久久99久播 | 免费观看人在逋| 波多野结衣巨乳人妻| 国产精品一区二区三区四区久久| 99久久人妻综合| 亚洲成人中文字幕在线播放| 免费在线观看成人毛片| 久久久午夜欧美精品| 欧美色视频一区免费| 插逼视频在线观看| 最近手机中文字幕大全| 欧美区成人在线视频| 99久久无色码亚洲精品果冻| 久久久精品大字幕| 久久婷婷人人爽人人干人人爱| 亚洲精品456在线播放app| 国产精品国产三级专区第一集| 中文乱码字字幕精品一区二区三区 | 精品国产一区二区三区久久久樱花 | 一级黄片播放器| 两个人的视频大全免费| 午夜福利视频1000在线观看| 亚洲经典国产精华液单| 69人妻影院| 亚洲精华国产精华液的使用体验| 久久精品影院6| 观看免费一级毛片| 国产成年人精品一区二区| 中文在线观看免费www的网站| 搡女人真爽免费视频火全软件| 久久久久性生活片| 国产精品国产三级专区第一集| 亚洲人与动物交配视频| 久久久午夜欧美精品| 水蜜桃什么品种好| 22中文网久久字幕| 午夜激情欧美在线| 亚洲真实伦在线观看| 熟女人妻精品中文字幕| 在线观看av片永久免费下载| 午夜爱爱视频在线播放| 又粗又爽又猛毛片免费看| 99在线视频只有这里精品首页| av天堂中文字幕网| 亚洲欧美清纯卡通| 人妻夜夜爽99麻豆av| 日本一二三区视频观看| 精品熟女少妇av免费看| 欧美色视频一区免费| 永久网站在线| 99在线视频只有这里精品首页| 永久网站在线| 日本欧美国产在线视频| 中文天堂在线官网| 免费黄色在线免费观看| 2021天堂中文幕一二区在线观| 人妻系列 视频| 蜜臀久久99精品久久宅男| 国产中年淑女户外野战色| 日韩一本色道免费dvd| 能在线免费观看的黄片| 男女啪啪激烈高潮av片| 国产视频内射| 亚洲精品日韩av片在线观看| 久久草成人影院| 免费观看a级毛片全部| 国产精品久久久久久久久免| www日本黄色视频网| 久久精品国产99精品国产亚洲性色| 久久99精品国语久久久| 亚洲一区高清亚洲精品| 精品久久久久久久久亚洲| 特大巨黑吊av在线直播| 亚洲欧美成人综合另类久久久 | 久久精品影院6| 免费人成在线观看视频色| 麻豆国产97在线/欧美| 免费观看精品视频网站| 亚洲国产欧美人成| 亚洲欧美成人精品一区二区| 成人漫画全彩无遮挡| 伦精品一区二区三区| 日韩成人av中文字幕在线观看| 国产探花极品一区二区| 一个人观看的视频www高清免费观看| 成年版毛片免费区| 18禁裸乳无遮挡免费网站照片| 色网站视频免费| 国语对白做爰xxxⅹ性视频网站| 全区人妻精品视频| 成人av在线播放网站| 国内少妇人妻偷人精品xxx网站| 最近2019中文字幕mv第一页| 汤姆久久久久久久影院中文字幕 | 国产乱人偷精品视频| 久久精品夜夜夜夜夜久久蜜豆| 中文字幕免费在线视频6| 亚洲av成人精品一二三区| 国产久久久一区二区三区| 国产成人免费观看mmmm| 精品久久久噜噜| 99在线人妻在线中文字幕| a级一级毛片免费在线观看| 国产视频首页在线观看| 高清视频免费观看一区二区 | 精品久久久久久成人av| 美女国产视频在线观看| 联通29元200g的流量卡| 狂野欧美激情性xxxx在线观看| 色5月婷婷丁香| 一个人免费在线观看电影| 少妇熟女aⅴ在线视频| 久久韩国三级中文字幕| 日本黄色视频三级网站网址| 简卡轻食公司| 午夜福利在线在线| 国产一级毛片在线| 国产精品久久久久久精品电影| 国产色爽女视频免费观看| 又粗又硬又长又爽又黄的视频| 日韩一区二区视频免费看| 嫩草影院精品99| 欧美人与善性xxx| 久久精品久久精品一区二区三区| av福利片在线观看| 国产片特级美女逼逼视频| 国产乱人视频| 一级av片app| 日本wwww免费看| 最近最新中文字幕大全电影3| 国产成人精品婷婷| 亚洲无线观看免费| 亚洲国产精品成人综合色| 最近中文字幕2019免费版| 国产老妇伦熟女老妇高清| 日韩精品青青久久久久久| 成人二区视频| 久久久成人免费电影| 黄色欧美视频在线观看| 欧美性猛交╳xxx乱大交人| 天天一区二区日本电影三级| 丰满少妇做爰视频| 久久久久久九九精品二区国产| 舔av片在线| 别揉我奶头 嗯啊视频| 日韩欧美三级三区| 一级毛片aaaaaa免费看小| 亚洲av电影在线观看一区二区三区 | 欧美3d第一页| 亚洲美女视频黄频| 久久精品熟女亚洲av麻豆精品 | 欧美成人a在线观看| 欧美三级亚洲精品| 久久精品国产亚洲网站| 男女下面进入的视频免费午夜| 观看免费一级毛片| or卡值多少钱| 欧美激情久久久久久爽电影| 亚洲四区av| 婷婷色麻豆天堂久久 | 亚洲自偷自拍三级| 人人妻人人看人人澡| 国产黄色小视频在线观看| 亚洲成人av在线免费| av女优亚洲男人天堂| av在线观看视频网站免费| 特大巨黑吊av在线直播| 国产欧美另类精品又又久久亚洲欧美| 97超碰精品成人国产| 91在线精品国自产拍蜜月| 老司机影院毛片| 好男人在线观看高清免费视频| 国产亚洲5aaaaa淫片| 亚洲av电影不卡..在线观看| 国产高清视频在线观看网站| 免费av观看视频| av在线播放精品| 亚洲国产高清在线一区二区三| 三级毛片av免费| 哪个播放器可以免费观看大片| 国产大屁股一区二区在线视频| 国产精品日韩av在线免费观看| 久久精品国产亚洲av涩爱| 欧美成人一区二区免费高清观看| 国内少妇人妻偷人精品xxx网站| 一级av片app| 精品国产三级普通话版| 亚洲美女搞黄在线观看| 国内揄拍国产精品人妻在线| 内地一区二区视频在线| 久久精品久久久久久噜噜老黄 | 亚洲av免费高清在线观看| 亚洲av日韩在线播放| 乱系列少妇在线播放| 亚洲精品乱码久久久久久按摩| 精品久久久久久久久av| 午夜精品一区二区三区免费看| 亚洲精品色激情综合| 亚洲精品乱码久久久v下载方式| 男女下面进入的视频免费午夜| 亚洲国产成人一精品久久久| 免费播放大片免费观看视频在线观看 | 女人被狂操c到高潮| 久久国产乱子免费精品| 特大巨黑吊av在线直播| 久久国产乱子免费精品| 女的被弄到高潮叫床怎么办| 久久99精品国语久久久| 成人鲁丝片一二三区免费| 91aial.com中文字幕在线观看| 成人鲁丝片一二三区免费| 日本午夜av视频| 九九爱精品视频在线观看| 99久久精品热视频| 级片在线观看| www.色视频.com| 真实男女啪啪啪动态图| 日韩欧美三级三区| 老女人水多毛片| 国产高清视频在线观看网站| 久久久久久久亚洲中文字幕| 日韩大片免费观看网站 | 欧美不卡视频在线免费观看| 女人十人毛片免费观看3o分钟| 特级一级黄色大片| 日本免费a在线| 日本熟妇午夜| 女人十人毛片免费观看3o分钟| 亚洲国产精品合色在线| 欧美激情在线99| 两性午夜刺激爽爽歪歪视频在线观看| 观看美女的网站| 亚洲欧美日韩东京热| 欧美zozozo另类| 看免费成人av毛片| 69av精品久久久久久| 欧美+日韩+精品| 一级毛片久久久久久久久女| 一个人看视频在线观看www免费| 国产成人福利小说| 国产午夜精品一二区理论片| 偷拍熟女少妇极品色| 久久久久国产网址| 美女内射精品一级片tv| 国产亚洲av嫩草精品影院| 国产熟女欧美一区二区| 天天躁日日操中文字幕| 中文亚洲av片在线观看爽| 老司机影院成人| 在线观看av片永久免费下载| 韩国av在线不卡| 日韩中字成人| 欧美成人午夜免费资源| 日日撸夜夜添| 又黄又爽又刺激的免费视频.| 日韩欧美三级三区| 久久精品熟女亚洲av麻豆精品 | 亚洲国产高清在线一区二区三| 毛片女人毛片| 国产午夜福利久久久久久| av女优亚洲男人天堂| ponron亚洲| 日韩一区二区三区影片| 97人妻精品一区二区三区麻豆| 久久久国产成人精品二区| 国产极品天堂在线| 国产精品一二三区在线看| 中文欧美无线码| 中文字幕亚洲精品专区| 美女大奶头视频| 国产91av在线免费观看| 高清日韩中文字幕在线| 欧美97在线视频| 国产视频首页在线观看| 搞女人的毛片| 国产成人a∨麻豆精品| 亚洲国产精品合色在线| 久久午夜福利片| 亚洲欧美精品自产自拍| 51国产日韩欧美| 亚洲综合色惰| 两性午夜刺激爽爽歪歪视频在线观看| 成人av在线播放网站| www.色视频.com| 内射极品少妇av片p| 水蜜桃什么品种好| 国产私拍福利视频在线观看| 一个人看视频在线观看www免费| 能在线免费观看的黄片| 亚洲av.av天堂| 国产精品99久久久久久久久| 精品一区二区三区视频在线| 久久99热这里只有精品18| 国产伦一二天堂av在线观看| 久久久国产成人免费| 久久久成人免费电影| 久久精品国产亚洲av涩爱| 国产美女午夜福利| 丰满人妻一区二区三区视频av| 人妻制服诱惑在线中文字幕| 精品无人区乱码1区二区| 亚洲自偷自拍三级| 亚洲经典国产精华液单| 超碰97精品在线观看| 九色成人免费人妻av| 九九在线视频观看精品| 亚洲欧美精品综合久久99| 国产亚洲最大av| 国产精品一区二区性色av|