本篇文章主要內容摘選自 Linux程序的常用保護機制、GCC 安全編譯選項、GCC安全保護機制,在本篇文章中,主要梳理匯總,便於以后查閱。
操作系統內置的安全機制
此處只總結和程序執行過程相關的安全機制,其他種類的安全機制與本文無關,暫不介紹。
Windows
-
DEP,全程為
Data Execution Prevention
,Windows系統內置的內存保護機制,自從XP和Server 20003開始引進。DEP使得系統能夠標記一個或多個內存頁的屬性為不可執行,這意味着代碼不能在該內存頁中執行,這有助於緩解緩沖區溢出攻擊的危害。如果一個應用嘗試在受保護的內存頁中運行代碼,將會觸發內存訪問異常,如果應用未處理該異常,默認處理會終止該進程。 -
ASLR,
Address Space layout randomization
加載地址隨機化機制,開啟方式:VS開發環境中的鏈接器下的高級選項中可以設置映像隨機化、堆棧隨機化、PEB和TEB隨機化等。
-
GS機制,緩沖區安全檢查,開啟此功能,編譯器會為每個函數調用的入口增加額外的隨機數(該隨機數稱為canary),它位於EBP之前,同時在.data內存區存放該隨機數副本。當函數棧發生溢出時,它會被覆蓋,函數在返回之前會比較.data區中副本的值和棧幀真實值,如果兩者不相等,則觸發異常處理流程。
開啟方式:VS開發環境中的C/C++下的代碼生成中的開啟緩沖區安全檢查。
Linux
-
NX機制,No-Execute,同Windows上的DEP功能類似,將數據所在內存頁標志為不可執行,當程序溢出轉入shellcode時,會嘗試在數據頁上執行指令,此時CPU會拋出異常。
關閉NX機制,編譯時增加 -z execstack
開啟NX機制,編譯時增加 -z noexecstack(默認開啟) -
PIE機制,Position-independent executables,位置獨立的可執行區域。同Windows系統的ASLR功能類似,一般同NX機制配合使用,能有效組織在堆棧上運行惡意代碼。PIE機制有三種工作模式,
- 工作模式0:關閉進程地址空間隨機化
- 工作模式1:開啟mmap機制、stack和vdso的地址隨機化
- 工作模式2:在1的基礎上,增加堆地址隨機化
系統級別關閉PIE echo 0 > /proc/sys/kernel/randomize_va_space
開啟PIE的工作模式1,在編譯時增加 -fpie -pie
開啟PIE的工作模式2,在編譯時增加 -fPIE -pie(默認開啟)
系統級別的PIE決定程序運行棧和堆段的地址隨機化。
編譯器的PIE選項決定程序靜態段(bss、data、text)地址隨機化。
GCC編譯器中的參數PIE和PIC都可生成位置無關的代碼,PIE主要用在可執行文件上,PIC用在共享庫上。
-
Cannary棧保護,同Windows上的GS機制,一種預防緩沖區溢出的手段,通常攻擊者通過覆蓋函數調用棧的返回地址來執行shellcode,在啟動棧保護機制后,在函數開始執行時會往棧里插入cookie信息,當函數真正返回時會驗證cookie信息是否合法,不合法則終止程序執行。Linux把這種在編譯期間插入的信息稱之為Canary。
開啟Cannary棧保護,在編譯時增加 -fstack-protector(只為含char數組的函數加入保護代碼) 和 -fstack-protector-all(為所有函數加入保護代碼)
關閉Cannary棧保護,在編譯時增加 -fno-stack-protector(默認不開啟)
Cannary機制還會調整局部變量的順序。如果數組地址在其他變量地址下面,那么數組緩沖區溢出后,可能修改其他變量的數值,當其他變量是函數指針時,就可被跳轉到shellcode上執行。將將數組移到高位地址后,緩沖區溢出的地址面對的是Cannary值保護,這樣可加大溢出攻擊的難度。這種保護方法只對函數棧中的控制信息(cannary word,EBP)和返回地址進項保護,沒有對局部變量進行保護。
-
RelRo機制
GCC, GNU linker以及Glibc-dynamic linker一起配合實現了一種叫做relro的技術(read only relocation)。大概實現就是由linker指定binary的一塊經過dynamic linker處理過之后的區域為只讀。設置符號重定向表格為只讀或在程序啟動時就解析並綁定所有動態符號,從而減少對GOT(Global Offset Table)攻擊。全部開啟RelRo機制:在編譯時增加 -z now
部分開啟RelRo機制:在編譯時增加 -z lazy(默認配置)
關閉RelRo機制: 在編譯時增加 -z norelro
查看可執行文件安全機制開啟情況
通過檢查可執行文件的屬性來查看安全機制開啟情況,可以使用 checksec來查看。