buffer overflow concepts
造成緩衝區溢位的目的是改變程序流程,使緩衝區溢位後執行攻擊者的攻擊代碼,此核心技術是溢出點的定位。
成功會控制EIP暫存器
ps: 很久以前就有的安全問題,利用程式語言中指標的弱點,新的程式語言己漸漸避免
導致buffer overflow原因
bad quality assurance on software produced
包括宣告變數時範圍設太小,沒有檢查使用者的輸入,…等
容易有問題function如
strcpy(),strcat(),streadd(),sprintf(),vsprintf(),bcopy(),gets(),scanf()
reasons for buffer overflow attacks
buffer overflow attacks depend on two thing:
the lack of boundary testing
a machine that can execute a code that resides in the data/stack segment
…………………
knowledge required to program buffer overflow exploits:
c functions and the stack
a little knowledge of assembly/machine language
how system calls are made(at the machine code level)
exec() system calls
how to guess some key parameters
要了解assembly language的重點有:
push:put one item on the top of the stack
pop:remove one item from the top of the stack
eip(extended instruction pointer):存放下一個CPU指令存放的記憶體位置,當cpu執行完目前指令後,會從eip register內讀取下一條指令的記憶體位置,然後繼續執行
esp(extended stack pointer):存放目前線程的stack指針
ebp(extended base pointer):保存目前線程的base指針
……………………………
types of buffer overflows:
stack based buffer overflow
經由設定過長的資料來讓stack中buffer的overflow,而主要造成的問題是return addr若是遭到更改,
對方就可以把return addr指向攻擊者植入的程式碼,當目前的函式執行完,就會去執行植入的程式碼。
heap based buffer overflow
通常要和stack overflow來配合,入侵者會把程式碼放在heap中,
再利用stack overflow來改寫return addr,把它指向heap。
ps:
stack
a contiguous block of memory containing data
用來存放function return address和function的local variables(包括參數)及保存暫存器值的記憶體空間。
是自動分配變量,以及函數調用的時候所使用的一些空間。地址是由高向低減少的。
就是我們平時所說的局部變量
heap
an area of memory utilized by an application and allocated dynamically at runtime
程式中動態配置記憶體所用的記憶體空間
是由malloc之類函數分配的空間所在地。地址是由低向高增長的。
例如malloc 與new出來的東西用指針指向了它,所指的地方就是heap
…
shellcode
a method to exploit stack-based overflows
shell code大致如下
char shellcode[]=”x31xc0x31xdbxb0x17xcdx80″
“x31xdbx89xd8xb0x2excdx80xd8xb0x2excdx80”
內容可以是指令或system call,…等,通常是執行system call
ps:x表示16進位
shellcode creation tool:
hellkit
…
null byte:
when write shellcodes,must avoid null bytes because these will end the string
NOP(no operation)
要求系統不做任何事
在 shellcode前加入一些nop可調整shellcode執行的更精準
nop machine code is 0x90 ,size is 1 byte
ps:
buffer overflow在ids的log可能如下
ids181/nops-x86: 64.225.80.12:1351 -> 173.17.2.105:53
polymorphiz shellcode
將shellcode加以變化欺騙ids
通常做法為:1xor編碼,2再用loader解碼後執行
tool 有admutate
…
緩衝區溢出攻擊的方法類別
棧溢出(stack smashing)
未檢查輸入緩衝區長度,導致陣列越界,覆蓋棧中局部變數空間之上的棧楨指標%ebp以及函數返回位址retaddr,當函數返回執行ret指令 時,retaddr從棧中彈出,作為下一條指令的位址賦給%eip寄存器,繼而改變原程式的執行流程指向我們的shellcode。
堆溢出(malloc/free heap corruption)
一種是和傳統的棧溢出一樣,當輸入超出malloc()預先分配的空間大小,就會覆蓋掉這段空間之後的一段存儲區域,如果該存儲區域有一個重要的變數比如 euid,那麼我就可以用它來攻擊。另一種是典型的double-free堆腐敗,在記憶體回收操作中,合併相鄰空閒塊重新插入雙向鏈表時會有一個寫4位 元組記憶體的操作,如果弱點程式由於編程錯誤free()一個不存在的塊,我們就可以精心偽造這個塊,從而覆蓋任何我們想要的值:函數的返回位址、庫函數 的.plt地址等
格式化字元竄漏洞(format string vulnerability)
如果格式竄由用戶定制,攻擊者就可以任意偽造格式竄,利用*printf()系列函數的特性就可以窺探堆疊空間的內容,超常輸入可以引發傳統的緩衝區溢出,或是用”%n”覆蓋指針、返回位址等。
整形變數溢出(integer variable overflow)
利用整數的範圍、符號等問題觸發安全漏洞,大多數整形溢出不能直接利用,但如果該整形變數決定記憶體分配等操作,我們就有可能間接利用該漏洞。
其他的攻擊手法(others)
只能算是手法,不能算是一種單獨的類別。利用ELF檔格式的特性如:覆蓋.plt(過程連接表)、.dtor(析構函數指標)、.got(全局偏移表)、 return-to-libc(返回庫函數)等的方式進行攻擊。
……………………………
tools to defend buffer overflow
RAD(return address defender):保護return address,避免被蓋掉
stackguard:保護stack不會被亂改,在compiler時就可以做到,因為在compiler時分析程式並加入一些code進去做保護
lnsure++
comodo memory firewall:保護記憶體
defenceplus: 保護記憶區段不會被蓋掉
buffershield:保護記憶體位置,支援ASLR(address space layout randomization)
編譯保護技術
Stackguard
因為緩衝區溢出的通常都會改寫函數返回位址,stackguard是個編譯器補丁,它產生一個”canary”值(一個單字)放到返回位址的前面,如果當函數返回時,發現這個canary的值被改變了,就證明可能有人正在試圖進行緩衝區溢出攻擊,程式會立刻回應,發送一條入侵警告消息給syslogd,然後終止進程。
canary包含:NULL(0x00),CR(0x0d),LF(0x0a),EOF(0xff)四個字符,它們應該可以阻止大部分的字串操作,使溢出攻擊無效。
一個亂數canary在程式執行的時候被產生。所以攻擊者不能通過搜索程式的二進位檔得 到"canary"值。
如果/dev/urandom存在,亂數就從那裏取得。否則,就從通過對當前時間進行編碼得到。其隨機性足以阻止絕大部分的預測攻 擊。
Immunix系統為採用stackguard編譯的Red Hat Linux,但stackguard所提供的保護並非絕對安全,滿足一些條件就可以突破限制:如覆蓋一個函數指標、可能存在的exit()或 _exit()系統調用位址、GOT等。
Stackshield
使用了另外一種不同的技術。它的做法是創建一個特別的堆疊用來儲存函數返回位址的一份拷貝。它在受保護的函數的開頭和結尾分別增加 一段代碼,開頭處的代碼用來將函數返回位址拷貝到一個特殊的表中,而結尾處的代碼用來將返回位址從表中拷貝回堆疊。因此函數執行流程不會改變,將總是正確 返回到主調函數中。
在新的版本中已經增加了一些新的保護措施,當調用一個位址在非文本段內的函數指標時,將終止函數的執行。
Stackshield無法防禦只覆蓋%ebp的單字節溢出,同樣,我們也可以通過覆蓋其他的ELF結構來繞過限制。
庫函數鏈結保護
Formatguard
是個Glibc的補丁,遵循GPL,它使用特殊的CPP(gcc預編譯程序)宏取代原有的*printf()的參數統計方式,它會 比較傳遞給*printf的參數的個數和格式竄的個數,如果格式竄的個數大於實際參數的個數,就判定為攻擊行為,向syslogd發送消息並終止進程。
如 果弱點程式調用Glibc以外的庫,formatguard就無法保護。
Libsafe
是一個動態連結程式庫,在標準的C庫之前被載入,主要加固了gets(),strcpy(),strcat(),sprintf()……等 容易發生安全問題的C函數
它設計為只針對stack smashing && format string類型的攻擊。
棧不可執行
Solar designer’s nonexec kernel patch
從名字可以看出這是一個Linux上的內核補丁,該補丁最主要的特性是:用戶區堆疊不可執行[Non-executable User Stack]由於x86 CPU上並沒有提供頁(page)執行的bit位,所以該補丁通過減小代碼段的虛擬位址來區分資料段和代碼段,程式執行流返回 0xC0000000以下一段用戶堆疊空間的操作都被認為是緩衝區溢出攻擊行為,隨即產生一個通用保護異常而終止進程。
這樣把shellcode 安置在buffer或環境變數(都位於堆疊段)的exploit都會失效。
當然其安全也不是絕對的,利用PLT返回庫函數的文章裏詳細描述了突破該補丁的攻擊方法。
該補還有一些其他的特性:動態連結程式庫映射到位址低端(0x00開始)、限制符號鏈結攻擊、/tmp目錄限制、/proc目錄限制、execve系統調用加固等。
Solaris/SPARC nonexec-stack protection
在Solaris/SPARC下可以通過去掉堆疊的執行許可權來禁止堆疊段執行,方法如下,在/etc/system中加入兩條語句:
Set noexec_user_stack = 1
Set noexec_user_stack_log = 1
第一條禁止堆疊執行,第二條記錄所有嘗試在堆疊段運行代碼的活動。
Reboot之後才會生效。所有只讓棧不可執行的保護是有限的。
Return- to-libc、fake frame之類的技術都可以突破限制,不過棧不可執行的保護已經極大了提升
資料段不可執行
kNoX
Linux內核補丁,功能:資料段的頁不可執行,撤銷共用記憶體,加強對execve系統調用的限制,對檔描述符0、1、2的特殊處理,/proc目錄的限制,FIFO限制,符號鏈結限制,該補丁只支2.2內核。
RSX
Linux內核模組,資料段(stack、heap)不可執行
Exec shield
從內核態顯示的跟蹤一個應用程式所包含的可執行映射的最大虛擬位址,動態的維護這個”可執行虛擬位址的最大值”稱為”可執行限 界”,每次發生進程切換的時候調度進程就會用這個值更新代碼段描述符寫入GDT,exec-shield動態的跟蹤每個應用程式,所以每個程式運行時都有 不同的”可執行限界”,因為可執行限界通常是個很低的虛擬位址,所以除了stack以外mmap()映射的區域以及malloc()分配的空間都處在可執 行限界之上,因此都是不可執行的。
當然Exec-shield無法防禦跳轉到低16M位址空間和return-to-libc的攻擊,不過還是能阻止絕大多數把shellcode安置在資料段的攻擊。
……………………………
hardward level prevention of buffer overflow
intel q965 express chipset
amd athlon 64 processors
X86 CPU上採用4GB平坦模式,資料段和代碼段的線性位址是重疊的,頁面只要可讀就可以執行,所以上面提到的諸多內核補丁才會費盡心機設計了各種方法來使資 料段不可執行。
現在Alpha、PPC、PA-RISC、SPARC、SPARC64、AMD64、IA64都提供了頁執行bit位。
Intel 及AMD 新增加的頁執行比特位稱為NX安全技術,Windows XP SP2及Linux Kernel 2.6都支援NX,雖然這種硬體級的頁保護不如PaX那樣強,但硬體級別的支援無疑大大增加了軟體和作業系統的相容性,能夠使緩衝區溢出的防護得到普及。
……………………………
how to detect buffer overflows in a program
look at the source code:使用safe c function檢查boundary有沒有問題,並避免有問題的function
feed the application with huge amounts of data and check for the abnormal behavior
defense against buffer overflows
manual auditing of code:檢查是否使用不安全的function
disabling stack execution:安裝os-disabling stack execution
safer c library support
compiler techniques:
use canary defense against buffer overflow attacks
stackguard:lmmunix
ssp/propolice:freebsd
gs:microsoft