背景
Android應(yīng)用程序在很大程度上是用Java實現(xiàn)的,從設(shè)計上來說,Java本身是不存在內(nèi)存損壞問題。但事,使用JNI庫的本地應(yīng)用程序很容易出現(xiàn)這種錯誤。
Android在開發(fā)過程中,使用一些不安全的系統(tǒng)函數(shù),一些不好編程習(xí)慣都會導(dǎo)致開發(fā)的應(yīng)用容易存在內(nèi)存損壞(溢出、越界等)的漏洞,這種內(nèi)存的問題也是攻擊者的主要攻擊對象。
此類錯誤源于編程錯誤,導(dǎo)致程序訪問意外的內(nèi)存位置。在適當(dāng)?shù)臈l件下,攻擊者可以利用這種行為劫持易受攻擊程序的執(zhí)行流并執(zhí)行任意代碼。
利用內(nèi)存損壞的主要目標(biāo)通常是將程序流重定向到攻擊者放置匯編的機器指令(稱為shellcode)的位置。
下面就梳理下這種內(nèi)存不安全的一些表現(xiàn)形式
緩沖區(qū)溢出
這描述了一個編程錯誤,即應(yīng)用程序在特定操作的分配內(nèi)存范圍之外進(jìn)行寫入。攻擊者可以利用此漏洞覆蓋位于相鄰內(nèi)存中的重要控制數(shù)據(jù),如函數(shù)指針。緩沖區(qū)溢出以前是最常見的內(nèi)存損壞缺陷,但近年來由于多種因素而變得不那么普遍。值得注意的是,開發(fā)人員意識到使用不安全的C庫函數(shù)的風(fēng)險是一種常見的做法,而且捕獲緩沖區(qū)溢出錯誤相對簡單。但是,這類缺陷仍然還是存在的。
要識別潛在的緩沖區(qū)溢出,使用不安全的字符串函數(shù)(strcpy、strcat、其它以“str”前綴開頭的函數(shù)等)和潛在的易受攻擊的編程構(gòu)造,例如將用戶輸入復(fù)制到有限大小的緩沖區(qū)。
對于不安全的字符串函數(shù),應(yīng)將以下內(nèi)容視為危險標(biāo)志:Strcat、strcpy、strncat、strlcat、strlcpy、sprintf、gets。
越界訪問
錯誤的指針運算可能導(dǎo)致指針或索引引用超出預(yù)期內(nèi)存結(jié)構(gòu)(例如緩沖區(qū)或列表)邊界的位置。當(dāng)應(yīng)用程序試圖寫入越界地址時,會發(fā)生崩潰或意外行為。
如果攻擊者能夠控制目標(biāo)偏移量并在一定程度上操縱編寫的內(nèi)容,則可能會利用代碼執(zhí)行漏洞。
懸掛指針
當(dāng)刪除或取消分配具有對內(nèi)存位置的傳入引用的對象,但未重置對象指針時,會發(fā)生懸掛指針。
如果程序稍后使用懸空指針來調(diào)用已釋放對象的虛擬函數(shù),雖然也可以讀取或?qū)懭霊覓熘羔樢玫膶ο笞兞炕蚱渌麅?nèi)存結(jié)構(gòu)則,可能通過覆蓋原始vtable指針來劫持執(zhí)行。
整數(shù)溢出
當(dāng)算術(shù)運算的結(jié)果超過程序員定義的整數(shù)類型的最大值時,這將導(dǎo)致值“環(huán)繞”最大整數(shù)值,不可避免地導(dǎo)致存儲一個小值。相反,當(dāng)算術(shù)運算的結(jié)果小于整數(shù)類型的最小值時,當(dāng)結(jié)果大于預(yù)期值時,會發(fā)生整數(shù)下溢。特定整數(shù)上溢/下溢錯誤是否可利用取決于整數(shù)的使用方式。例如,如果整數(shù)類型表示緩沖區(qū)的長度,這可能會造成緩沖區(qū)溢出漏洞。
格式字符串漏洞
當(dāng)未經(jīng)檢查的用戶輸入被傳遞給C函數(shù)printf家族的格式字符串參數(shù)時,攻擊者可能會注入格式令牌(如“%C”和“%n”)以訪問內(nèi)存。由于其靈活性,格式化字符串錯誤易于利用。如果程序輸出字符串格式化操作的結(jié)果,攻擊者可以任意讀取和寫入內(nèi)存,從而繞過ASLR等保護(hù)功能。
常見格式字符串漏洞函數(shù)如下:
降低安全風(fēng)險小方案
1.當(dāng)使用整數(shù)變量進(jìn)行數(shù)組索引、緩沖區(qū)長度計算或任何其他安全關(guān)鍵操作時,請驗證是否使用了無符號整數(shù)類型,并執(zhí)行前提條件測試以防止整數(shù)換行的可能性。
2.不使用不安全的字符串函數(shù),如strcpy,大多數(shù)其他以“str”前綴開頭的函數(shù),sprint,vsprintf,gets等,可以采用安全的函數(shù)例如strncpy、memcpy_s等函數(shù)
3.如果應(yīng)用程序包含C++代碼,則使用ANSI C++字符串類;
4.如果是memcpy,請確保檢查目標(biāo)緩沖區(qū)至少與源緩沖區(qū)大小相同,并且兩個緩沖區(qū)不重疊。
5.不要使用沒有不受信任的數(shù)據(jù)連接到格式字符串中。
6.作為“for”或“while”循環(huán)實現(xiàn)的復(fù)制操作的實例,并驗證是否正確執(zhí)行了長度檢查。
小結(jié)
內(nèi)存損壞錯誤最好通過輸入模糊化來發(fā)現(xiàn):這是一種自動黑盒軟件測試技術(shù),通過這種技術(shù),畸形數(shù)據(jù)會不斷發(fā)送到應(yīng)用程序,以調(diào)查潛在的漏洞狀況。在此過程中,將監(jiān)控應(yīng)用程序的故障和崩潰。如果發(fā)生崩潰,希望(至少對安全測試人員來說)是造成崩潰的條件揭示了一個可利用的安全漏洞。
模糊測試技術(shù)或腳本(通常稱為“模糊器”)通常會以半正確的方式生成結(jié)構(gòu)化輸入的多個實例。本質(zhì)上,生成的值或參數(shù)至少部分被目標(biāo)應(yīng)用程序接受,但也包含無效元素,可能會觸發(fā)輸入處理缺陷和意外的程序行為。一個好的模糊器暴露了大量可能的程序執(zhí)行路徑(即高覆蓋輸出)。輸入要么從零開始生成,要么從變異已知的有效輸入數(shù)據(jù)中導(dǎo)出。
編輯:黃飛
?
評論