棧溢位保護是一種緩衝區溢位攻擊緩解手段,當函式存在緩衝區溢位攻擊漏洞時,攻擊者可以覆蓋棧上的返回位址來讓shellcode能夠得到執行。用canary是否變化來檢測,其中canary found表示開啟。
函式開始執行的時候會先往棧裡插入cookie資訊,當函式真正返回的時候會驗證cookie資訊是否合法,如果不合法就停止程式執行。攻擊者在覆蓋返回位址的時候往往也會將cookie資訊給覆蓋掉,導致棧保護檢查失敗而阻止shellcode的執行。在linux中我們將cookie資訊稱為canary。
gcc編譯新增引數-fno-stack-protector
或者-fno-stack-protector-all
gcc -o test test.c // 預設情況下,不開啟canary保護
gcc -fno-stack-protector -o test test.c //禁用棧保護
gcc -fstack-protector -o test test.c //啟用堆疊保護,不過只為區域性變數中含有 char 陣列的函式插入保護**
gcc -fstack-protector-all -o test test.c //啟用堆疊保護,為所有函式插入保護**
通過改寫指標與區域性變數、leak canary
、overwrite canary
的方法來繞過。
fority其實非常輕微的檢查,用於檢查是否存在緩衝區溢位的錯誤。適用情形是程式採用大量的字串或者記憶體操作函式,如memcpy,memset,stpcpy,strcpy,strncpy,strcat,strncat,sprintf,snprintf,vsprintf,vsnprintf,gets
以及寬字元的變體。
fortify 技術是gcc在編譯原始碼時判斷程式的哪些buffer會存在可能的溢位,在buffer大小已知的情況下,gcc會把strcpy
、memcpy
、memset
等函式自動替換成相應的__strcpy_chk
(dst
,src
,dstlen
)等函式,達到防止緩衝區溢位的作用。
fortify_source機制對格式化字串有兩個限制:
(1)包含%n的格式化字串不能位於程式記憶體中的可寫位址;
(2)當使用位置引數時,必須使用範圍內的所有引數。例如要使用%4$x,則必須同時使用1、2、3。
gcc中-d_fortify_source=2
是預設開啟的,但是只有開啟o2或以上優化的時候,這個選項才會被真正啟用。
如果指定-d_fortify_source=1
,那同樣也要開啟o1或以上優化,這個選項才會被真正啟用。
可以使用-u_fortify_source
或者-d_fortify_source=0
來禁用。
如果開啟了-d_fortify_source=2
,那麼呼叫__printf_chk
函式的時候會檢查format string中是否存在%n
,如果存在%n
而且format string是在乙個可寫的segment中的(不是在read-only記憶體段中),那麼程式會報錯並終止。如果是開啟-d_fortify_source=1
,那麼就不會報錯
gcc -d_fortify_source=1
僅僅只會在編譯時進行檢查 (特別像某些標頭檔案#include
)
gcc -d_fortify_source=2
程式執行時也會有檢查 (如果檢查到緩衝區溢位,就終止程式)
gcc -o test test.c // 預設情況下,不會開這個檢查
gcc -d_fortify_source=1 -o test test.c // 較弱的檢查
gcc -d_fortify_source=2 -o test test.c // 較強的檢查
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保護
使用 rop(return-oriented programming)繞過
如ret2data、ret2libc、ret2strcpy、ret2gets、ret2syscall
gadget:virtualprotect、jmp esp、mona.py
一般情況下nx(windows平台上稱其為dep)和位址空間分布隨機化(aslr)會同時工作。
(1)aslr(address space layout randomization):
位址隨機化,通常用來防禦return2libc攻擊。
(2)pie(position-independent executables):
位置無關的可執行檔案,和windows下的aslr(address space layout randomization)機制類似,pie enabled表示程式開啟位址隨機化選、意味著程式每次執行的時候位址都會變化。主要是為了解決二進位制本身位址已知的問題,可用來防禦return2elf和其他已知位址讀寫問題。
0 - 表示關閉程序位址空間隨機化。
1 - 表示將mmap的基址,stack和vdso頁面隨機化。
2 - 表示在1的基礎上增加棧(heap)的隨機化。
可以防範基於ret2libc方式的針對dep的攻擊。aslr和dep配合使用,能有效阻止攻擊者在堆疊上執行惡意**。
built as pie:位置獨立的可執行區域(position-independent executables)。這樣使得在利用緩衝溢位和移動作業系統中存在的其他記憶體崩潰缺陷時採用面向返回的程式設計(return-oriented programming)方法變得難得多。
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
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
在linux系統安全領域資料可以寫的儲存區就會是攻擊的目標,尤其是儲存函式指標的區域。 所以在安全防護的角度來說儘量減少可寫的儲存區域對安全會有極大的好處.
gcc, gnu linker以及glibc-dynamic linker一起配合實現了一種叫做relro的技術: read only relocation。大概實現就是由linker指定binary的一塊經過dynamic linker處理過 relocation之後的區域為唯讀.用來防禦hijack got攻擊。
設定符號重定向**為唯讀或在程式啟動時就解析並繫結所有動態符號,從而減少對got(global offset table)攻擊。relro為」 partial relro」,說明我們對got表具有寫許可權。
relro有partial relro和full relro兩個選項,如果開啟full relro,意味著無法修改got表;如果為partial relro,說明對got表具有寫許可權。在linux下預設開啟狀態。
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 // 全部開啟,即
可通過rop繞過
elf安全防禦機制小結:安全防禦機制小結/
linux保護機制整理:
canary保護詳解和常用bypass手段:
linux程式的常用保護機制
linux nx pie windows dep aslr dep是資料執行保護的英文縮寫,全稱為data execution prevention。資料執行保護 dep 是一套軟硬體技術,能夠在記憶體上執行額外檢查以幫助防止在系統上執行惡意 nx即no execute 不可執行 的意思,nx de...
Linux下程式的保護機制 checksec
相信很多人,檢視程式資訊時會用到,checksec這個命令。它會給你返回如下圖的結果,但是很多最開始看到的人,很多都看不懂,如果身為小白的我,跟在大佬後面比葫蘆畫瓢,這樣用。這篇博文就是用來解釋下面資訊的,希望對你有所幫助,同時也是為了以後自己忘記可以回顧。stack canray是專門針對棧溢位攻...
Ret2shellcode和NX保護機制
ret2text漏洞利用依賴於程式中存在執行system bin sh 的函式,如果沒有這個函式,怎麼辦呢?沒有執行shell的函式,沒有開啟nx保護 我們需要傳入自定義shellcode,這就利用方式就是ret2shellcode shellcode是黑客編寫的用於實行特定功能的彙編 通常是開啟乙...