成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

APP漏洞掃描用地址空間隨機(jī)化

LinkedME2016 / 999人閱讀

摘要:同時(shí),阿里聚漏洞掃描器有一個(gè)檢測(cè)項(xiàng)叫未使用地址空間隨機(jī)化技術(shù)該檢測(cè)項(xiàng)會(huì)分析中包含的文件判斷它們是否使用了該項(xiàng)技術(shù)。在版本上線前使用阿里聚安全漏洞掃描系統(tǒng)進(jìn)行安全掃描,將安全隱患阻擋在發(fā)布之前。

前言

我們?cè)谇拔摹禔PP漏洞掃描器之本地拒絕服務(wù)檢測(cè)詳解》了解到阿里聚安全漏洞掃描器有一項(xiàng)靜態(tài)分析加動(dòng)態(tài)模糊測(cè)試的方法來檢測(cè)的功能,并詳細(xì)的介紹了它在針對(duì)本地拒絕服務(wù)的檢測(cè)方法。

同時(shí),阿里聚漏洞掃描器有一個(gè)檢測(cè)項(xiàng)叫未使用地址空間隨機(jī)化技術(shù), 該檢測(cè)項(xiàng)會(huì)分析APP中包含的ELF文件判斷它們是否使用了該項(xiàng)技術(shù)。如果APP中存在該項(xiàng)漏洞則會(huì)降低緩沖區(qū)溢出攻擊的門檻。

本文主要介紹該項(xiàng)技術(shù)的原理和掃描器的檢測(cè)方法。由于PIE的實(shí)現(xiàn)細(xì)節(jié)較復(fù)雜,本文只是介紹了大致的原理。想深入了解細(xì)節(jié)的同學(xué)可以參看潘愛民老師的書籍《程序員的自我修養(yǎng)》。

PIE是什么

PIE(position-independent executable)是一種生成地址無關(guān)可執(zhí)行程序的技術(shù)。如果編譯器在生成可執(zhí)行程序的過程中使用了PIE,那么當(dāng)可執(zhí)行程序被加載到內(nèi)存中時(shí)其加載地址存在不可預(yù)知性。

PIE還有個(gè)孿生兄弟PIC(position-independent code)。其作用和PIE相同,都是使被編譯后的程序能夠隨機(jī)的加載到某個(gè)內(nèi)存地址。區(qū)別在于PIC是在生成動(dòng)態(tài)鏈接庫時(shí)使用(Linux中的so),PIE是在生成可執(zhí)行文件時(shí)使用。

PIE的作用

安全性

PIE可以提高緩沖區(qū)溢出攻擊的門檻。它屬于ASLR(Address space layout randomization)的一部分。ASLR要求執(zhí)行程序被加載到內(nèi)存時(shí),它其中的任意部分都是隨機(jī)的。包括
Stack, Heap ,Libs and mmap, Executable, Linker, VDSO。通過PIE我們能夠?qū)崿F(xiàn)Executable 內(nèi)存隨機(jī)化

節(jié)約內(nèi)存使用空間

除了安全性,地址無關(guān)代碼還有一個(gè)重要的作用是提高內(nèi)存使用效率。

一個(gè)共享庫可以同時(shí)被多個(gè)進(jìn)程裝載,如果不是地址無關(guān)代碼(代碼段中存在絕對(duì)地址引用),每個(gè)進(jìn)程必須結(jié)合其自生的內(nèi)存地址調(diào)用動(dòng)態(tài)鏈接庫。導(dǎo)致不得不將共享庫整體拷貝到進(jìn)程中。如果系統(tǒng)中有100個(gè)進(jìn)程調(diào)用這個(gè)庫,就會(huì)有100份該庫的拷貝在內(nèi)存中,這會(huì)照成極大的空間浪費(fèi)。

相反如果被加載的共享庫是地址無關(guān)代碼,100個(gè)進(jìn)程調(diào)用該庫,則該庫只需要在內(nèi)存中加載一次。這是因?yàn)镻IE將共享庫中代碼段須要變換的內(nèi)容分離到數(shù)據(jù)段。使得代碼段加載到內(nèi)存時(shí)能做到地址無關(guān)。多個(gè)進(jìn)程調(diào)用共享庫時(shí)只需要在自己的進(jìn)程中加載共享庫的數(shù)據(jù)段,而代碼段則可以共享。

PIE工作原理簡介

我們先從實(shí)際的例子出發(fā),觀察PIE和NO-PIE在可執(zhí)行程序表現(xiàn)形式上的區(qū)別。管中窺豹探索地址無關(guān)代碼的實(shí)現(xiàn)原理。

例子一

定義如下C代碼:

#include 

int global;

void main()
{
    printf("global address = %x
", &global);
}

程序中定義了一個(gè)全局變量global并打印其地址。我們先用普通的方式編譯程序。

gcc -o sample1 sample1.c

運(yùn)行程序可以觀察到global加載到內(nèi)存的地址每次都一樣。

$./sample1
global address = 6008a8
$./sample1
global address = 6008a8
$./sample1
global address = 6008a8

接著用PIE方式編譯 sample1.c

gcc -o sample1_pie sample1.c -fpie -pie

運(yùn)行程序觀察global的輸出結(jié)果:

./sample1_pie
global address = 1ce72b38
./sample1_pie
global address = 4c0b38
./sample1_pie
global address = 766dcb38

每次運(yùn)行地址都會(huì)發(fā)生變換,說明PIE使執(zhí)行程序每次加載到內(nèi)存的地址都是隨機(jī)的。

例子二

在代碼中聲明一個(gè)外部變量global。但這個(gè)變量的定義并未包含進(jìn)編譯文件中。

#include 

extern int global;

void main()
{
    printf("extern global address = %x
", &global);
}

首先使用普通方式編譯 extern_var.c。在編譯選項(xiàng)中故意不包含有g(shù)lobal定義的源文件。

gcc -o extern_var extern_var.c

發(fā)現(xiàn)不能編譯通過, gcc提示:

/tmp/ccJYN5Ql.o: In function `main":
extern_var.c:(.text+0xa): undefined reference to `global"
collect2: ld returned 1 exit status

編譯器在鏈接階段有一步重要的動(dòng)作叫符號(hào)解析與重定位。鏈接器會(huì)將所有中間文件的數(shù)據(jù),代碼,符號(hào)分別合并到一起,并計(jì)算出鏈接后的虛擬基地址。比如 “.text”段從 0x1000開始,”.data”段從0x2000開始。接著鏈接器會(huì)根據(jù)基址計(jì)算各個(gè)符號(hào)(global)的相對(duì)虛擬地址。

當(dāng)編譯器發(fā)現(xiàn)在符號(hào)表中找不到global的地址時(shí)就會(huì)報(bào)出 undefined reference to `global`. 說明在靜態(tài)鏈接的過程中編譯器必須在編譯鏈接階段完成對(duì)所有符號(hào)的鏈接。

如果使用PIE方式將extern_var.c編譯成一個(gè)share library會(huì)出現(xiàn)什么情況呢?

gcc -o extern_var.so extern_var.c -shared -fPIC

程序能夠順利編譯通過生成extern_var.so。但運(yùn)行時(shí)會(huì)報(bào)錯(cuò),因?yàn)檠b載時(shí)找不到global符號(hào)目標(biāo)地址。這說明-fPIC選項(xiàng)生成了地址無關(guān)代碼。將靜態(tài)鏈接時(shí)沒有找到的global符號(hào)的鏈接工作推遲到裝載階段。

那么在編譯鏈接階段,鏈接器是如何將這個(gè)缺失的目標(biāo)地址在代碼段中進(jìn)行地址引用的呢?

鏈接器巧妙的用一張中間表GOT(Global Offset Table)來解決被引用符號(hào)缺失目標(biāo)地址的問題。如果在鏈接階段(jing tai)發(fā)現(xiàn)一個(gè)不能確定目標(biāo)地址的符號(hào)。鏈接器會(huì)將該符號(hào)加到GOT表中,并將所有引用該符號(hào)的地方用該符號(hào)在GOT表中的地址替換。到裝載階段動(dòng)態(tài)鏈接器會(huì)將GOT表中每個(gè)符號(hào)對(duì)應(yīng)的實(shí)際目標(biāo)地址填上。

當(dāng)程序執(zhí)行到符號(hào)對(duì)應(yīng)的代碼時(shí),程序會(huì)先查GOT表中對(duì)應(yīng)符號(hào)的位置,然后根據(jù)位置找到符號(hào)的實(shí)際的目標(biāo)地址。

地址無關(guān)代碼的生成方式

所謂地址無關(guān)代碼要求程序被加載到內(nèi)存中的任意地址都能夠正常執(zhí)行。所以程序中對(duì)變量或函數(shù)的引用必須是相對(duì)的,不能包含絕對(duì)地址。

比如如下偽匯編代碼:

PIE方式:代碼可以運(yùn)行在地址100或1000的地方

100: COMPARE REG1, REG2
101: JUMP_IF_EQUAL CURRENT+10
...
111: NOP

Non-PIE: 代碼只能運(yùn)行在地址100的地方

100: COMPARE REG1, REG2
101: JUMP_IF_EQUAL 111
...
111: NOP

因?yàn)榭蓤?zhí)行程序的代碼段只有讀和執(zhí)行屬性沒有寫屬性,而數(shù)據(jù)段具有讀寫屬性。要實(shí)現(xiàn)地址無關(guān)代碼,就要將代碼段中須要改變的絕對(duì)值分離到數(shù)據(jù)段中。在程序加載時(shí)可以保持代碼段不變,通過改變數(shù)據(jù)段中的內(nèi)容,實(shí)現(xiàn)地址無關(guān)代碼。

PIE和Non-PIE程序在內(nèi)存中映射方式

在Non-PIE時(shí)程序每次加載到內(nèi)存中的位置都是一樣的。

執(zhí)行程序會(huì)在固定的地址開始加載。系統(tǒng)的動(dòng)態(tài)鏈接器庫ld.so會(huì)首先加載,接著ld.so會(huì)通過.dynamic段中類型為DT_NEED的字段查找其他需要加載的共享庫。并依次將它們加載到內(nèi)存中。注意:因?yàn)槭荖on-PIE模式,這些動(dòng)態(tài)鏈接庫每次加載的順序和位置都一樣。

而對(duì)于通過PIE方式生成的執(zhí)行程序,因?yàn)闆]有絕對(duì)地址引用所以每次加載的地址也不盡相同。

不僅動(dòng)態(tài)鏈接庫的加載地址不固定,就連執(zhí)行程序每次加載的地址也不一樣。這就要求ld.so首先被加載后它不僅要負(fù)責(zé)重定位其他的共享庫,同時(shí)還要對(duì)可執(zhí)行文件重定位。

PIE與編譯器選項(xiàng)

GCC編譯器用于生成地址無關(guān)代碼的參數(shù)主要有-fPIC, -fPIE, -pie。

其中-fPIC, -fPIE屬于編譯時(shí)選項(xiàng),分別用于生成共享庫和可執(zhí)行文件。它們能夠使編譯階段生成的中間代碼具有地址無關(guān)代碼的特性。但這并不代表最后生成的可執(zhí)行文件是PIE的。還需要在鏈接時(shí)通過-pie選項(xiàng)告訴鏈接器生成地址無關(guān)代碼的可執(zhí)行程序。

一個(gè)標(biāo)準(zhǔn)的PIE程序編譯設(shè)置如下:

gcc -o sample_pie sample.c -fPIE -pie

在gcc中使用編譯選項(xiàng)與是否生成PIE可執(zhí)行文件對(duì)應(yīng)關(guān)系如下:

Type為DYN的程序支持PIE,EXEC類型不支持。DYN, EXEC與PIE對(duì)應(yīng)關(guān)系詳見后文。

ASLR在Android中的應(yīng)用

PIE屬于ASLR的一部分,如上節(jié)提到ASLR包括對(duì)Stack, Heap, Libs and mmap, Executable, Linker, VDSO的隨機(jī)化。

而支持PIE只表示對(duì)Executable實(shí)現(xiàn)了ASLR。隨著Android的發(fā)展對(duì)ASLR的支持也逐漸增強(qiáng)。

ASLR in Android 2.x

Android對(duì)ASLR的支持是從Android 2.x開始的。2.x只支持對(duì)Stack的隨機(jī)化。

ASLR in Android 4.0

而在4.0,即其所謂的支持ASLR的版本上,其實(shí)ASLR也僅僅增加了對(duì)libc等一些shared libraries進(jìn)行了隨機(jī)化,而對(duì)于heap, executable和linker還是static的。

對(duì)于heap的隨機(jī)化來說,可以通過

echo 2 > /proc/sys/kernel/randomize_va_space

來開啟。

而對(duì)于executable的隨機(jī)化,由于大部分的binary沒有加GCC的-pie -fPIE選項(xiàng),所以編譯出來的是EXEC,而不是DYN這種shared object file,因此不是PIE(Position Independent Executable),所以沒有辦法隨機(jī)化;

同樣的linker也沒有做到ASLR。

ASLR in Android 4.1

終于,在4.1 Jelly Bean中,Android支持了所有內(nèi)存的ASLR。在Android 4.1中,基本上所有binary都被編譯和連接成了PIE模式(可以通過readelf查看其Type)。所以,相比于4.0,4.1對(duì)Heap,executable和linker都提供了ASLR的支持。

ASLR in Android 5.0

5.0中Android拋棄了對(duì)non-PIE的支持,所有的進(jìn)程均是ASLR的。如果程序沒有開啟PIE,在運(yùn)行時(shí)會(huì)報(bào)錯(cuò)并強(qiáng)制退出。

PIE程序運(yùn)行在Android各版本

支持PIE的可執(zhí)行程序只能運(yùn)行在4.1+的版本上。 在4.1版本之前運(yùn)行會(huì)出現(xiàn)crash。而Non-PIE的程序,在5.0之前的版本能正常運(yùn)行,但在5.0上會(huì)crash。

如何檢測(cè)是否開啟PIE

未開啟PIE的執(zhí)行程序用readelf查看其文件類型應(yīng)顯示EXEC(可執(zhí)行文件),開啟PIE的可執(zhí)行程序的文件類型為DYN(共享目標(biāo)文件)。另外代碼段的虛擬地址總是從0開始。

為什么檢測(cè)DYN就可以判斷是否支持PIE?

DYN指的是這個(gè)文件的類型,即共享目標(biāo)文件。那么所有的共享目標(biāo)文件一定是開啟了PIE的嗎?我們可以從源碼中尋找答案。查看glibc/glibc-2.16.0/elf/dl-load.c中的代碼。

從源碼可知,如果加載類型不為ET_DYN時(shí)調(diào)用mmap加載文件時(shí)會(huì)傳入MAP_FIXED標(biāo)志。將程序映射到固定地址。

阿里聚安全開發(fā)中建議

針對(duì)Android 2.x-4.1之前的系統(tǒng)在編譯時(shí)不要使用生成PIE的選項(xiàng)。

在Android 4.1以后的版本必須使用PIE生成Native程序,提高攻擊者中的攻擊成本。

在版本上線前使用阿里聚安全漏洞掃描系統(tǒng)進(jìn)行安全掃描,將安全隱患阻擋在發(fā)布之前。

Reference

https://en.wikipedia.org/wiki...

http://www.openbsd.org/papers...

https://source.android.com/se...

http://ytliu.info/blog/2012/1...

https://codywu2010.wordpress....

http://www.cnblogs.com/huxiao...

http://stackoverflow.com/ques...

作者:呆狐@阿里聚安全 ,更多Android、iOS技術(shù)文章,請(qǐng)?jiān)L問阿里聚安全博客

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/11205.html

相關(guān)文章

  • 阿里90后工程師利ARM硬件特性開啟安卓8終端“上帝模式”

    摘要:然而,處理器的某些特殊硬件特性能夠打破這種保護(hù),使得普通程序在用戶態(tài)能夠直接訪問內(nèi)核空間,直接打破內(nèi)核空間與用戶空間的隔離,修改內(nèi)核代碼,開啟上帝模式。假設(shè)某臺(tái)安卓終端擁有內(nèi)存。至此,上帝模式已經(jīng)開啟。 文/圖 阿里安全潘多拉實(shí)驗(yàn)室 團(tuán)控 編者按:團(tuán)控,阿里安全潘多拉實(shí)驗(yàn)室研究人員,該實(shí)驗(yàn)室主要聚焦于移動(dòng)安全領(lǐng)域,包括對(duì)iOS和Android系統(tǒng)安全的攻擊和防御技術(shù)研究。團(tuán)控的主攻方向...

    RayKr 評(píng)論0 收藏0
  • SpringCloud(第 007 篇)電影微服務(wù),使定制 Ribbon 在客戶端進(jìn)行負(fù)載均衡不

    摘要:中的名稱,一定要是服務(wù)中注冊(cè)的名稱。添加這個(gè)的注解,主要是因?yàn)槎x的時(shí)候報(bào)錯(cuò),也就是說明沒有被實(shí)例化。采用隨機(jī)分配的策略。添加訪問層添加電影微服務(wù)啟動(dòng)類電影微服務(wù),使用定制化在客戶端進(jìn)行負(fù)載均衡,使用不同服務(wù)不同配置策略。 SpringCloud(第 007 篇)電影微服務(wù),使用定制化 Ribbon 在客戶端進(jìn)行負(fù)載均衡,使用 RibbonClient 不同服務(wù)不同配置策略 - 一、大...

    scola666 評(píng)論0 收藏0
  • 細(xì)數(shù)iOS上的那些安全防護(hù)

    摘要:序隨著蘋果對(duì)系統(tǒng)多年的研發(fā),上的安全防護(hù)機(jī)制也是越來越多,越來越復(fù)雜。代碼簽名為了保護(hù)開發(fā)者的版權(quán)以及防止盜版應(yīng)用,蘋果系統(tǒng)擁有非常嚴(yán)格的簽名保護(hù)機(jī)制。除了傳統(tǒng)的簽名機(jī)制以外,蘋果還額外增加了的安全防護(hù)措施,用來增強(qiáng)系統(tǒng)的安全性。 0x00 序 隨著蘋果對(duì)iOS系統(tǒng)多年的研發(fā),iOS上的安全防護(hù)機(jī)制也是越來越多,越來越復(fù)雜。這對(duì)于剛接觸iOS安全的研究人員來說非常不友好,往往不知從何入...

    shengguo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<