Linux中的保護機制html
在編寫漏洞利用代碼的時候,須要特別注意目標進程是否開啓了NX、PIE等機制,例如存在NX的話就不能直接執行棧上的數據,存在PIE 的話各個系統調用的地址就是隨機化的。shell
一:canary(棧保護)編程
棧溢出保護是一種緩衝區溢出攻擊緩解手段,當函數存在緩衝區溢出攻擊漏洞時,攻擊者能夠覆蓋棧上的返回地址來讓shellcode可以獲得執行。當啓用棧保護後,函數開始執行的時候會先往棧裏插入cookie信息,當函數真正返回的時候會驗證cookie信息是否合法,若是不合法就中止程序運行。攻擊者在覆蓋返回地址的時候每每也會將cookie信息給覆蓋掉,致使棧保護檢查失敗而阻止shellcode的執行。在Linux中咱們將cookie信息稱爲canary。數組
gcc在4.2版本中添加了-fstack-protector和-fstack-protector-all編譯參數以支持棧保護功能,安全
所以在編譯時能夠控制是否開啓棧保護以及程度,例如:cookie
一、gcc -o test test.c // 默認狀況下,不開啓Canary保護dom
二、gcc -fno-stack-protector -o test test.c //禁用棧保護ide
三、gcc -fstack-protector -o test test.c //啓用堆棧保護,不過只爲局部變量中含有 char 數組的函數插入保護代碼函數
四、gcc -fstack-protector-all -o test test.c //啓用堆棧保護,爲全部函數插入保護代碼spa
二:NX(no execute)
NX即No-eXecute(不可執行)的意思,NX(DEP)的基本原理是將數據所在內存頁標識爲不可執行,當程序溢出成功轉入shellcode時,程序會嘗試在數據頁面上執行指令,此時CPU就會拋出異常,而不是去執行惡意指令。
gcc編譯器默認開啓了NX選項,若是須要關閉NX選項,能夠給gcc編譯器添加-z execstack參數。 例如:
一、gcc -o test test.c // 默認狀況下,開啓NX保護
二、gcc -z execstack -o test test.c // 禁用NX保護
三、gcc -z noexecstack -o test test.c // 開啓NX保護
在Windows下,相似的概念爲DEP(數據執行保護)
三:PIE(position-independent executables)
位置獨立的可執行區域。這樣使得在利用緩衝溢出和移動操做系統中存在的其餘內存崩潰缺陷時採用面向返回的編程(return-oriented programming)方法變得可貴多。通常狀況下NX(Windows平臺上稱其爲DEP)和地址空間分佈隨機化(ASLR)會同時工做。內存地址隨機化機制(address space layout randomization),有如下三種狀況:
0 - 表示關閉進程地址空間隨機化。
1 - 表示將mmap的基址,stack和vdso頁面隨機化。
2 - 表示在1的基礎上增長棧(heap)的隨機化。
liunx下關閉PIE的命令以下:
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
gcc編譯命令:
一、gcc -o test test.c // 默認狀況下,不開啓PIE
二、gcc -fpie -pie -o test test.c // 開啓PIE,此時強度爲1
三、gcc -fPIE -pie -o test test.c // 開啓PIE,此時爲最高強度2
四、gcc -fpic -o test test.c // 開啓PIC,此時強度爲1,不會開啓PIE
五、gcc -fPIC -o test test.c // 開啓PIC,此時爲最高強度2,不會開啓PIE
四:RELRO( read only relocation)
在Linux系統安全領域,數據能夠寫的存儲區就會是攻擊的目標,尤爲是存儲函數指針的區域。 因此在安全防禦的角度來講儘可能減小可寫的存儲區域對安全會有極大的好處。GCC, GNU linker以及Glibc-dynamic linker一塊兒配合實現了一種叫作relro的技術:。大概實現就是由linker指定binary的一塊通過dynamic linker處理過 relocation以後的區域爲只讀.設置符號重定向表格爲只讀或在程序啓動時就解析並綁定全部動態符號,從而減小對GOT(Global Offset Table)攻擊。RELRO爲」 Partial RELRO」,說明咱們對GOT表具備寫權限。
gcc編譯:
gcc -o test test.c // 默認狀況下,是Partial RELRO
gcc -z norelro -o test test.c // 關閉,即No RELRO
gcc -z lazy -o test test.c // 部分開啓,即Partial RELRO
gcc -z now -o test test.c // 所有開啓
五 總結
各類安全選擇的編譯參數以下:
參考資料: