本篇文章主要內容摘選自 Linux程序的經常使用保護機制、GCC 安全編譯選項、GCC安全保護機制,在本篇文章中,主要梳理彙總,便於之後查閱。html
此處只總結和程序執行過程相關的安全機制,其餘種類的安全機制與本文無關,暫不介紹。linux
DEP,全程爲Data Execution Prevention
,Windows系統內置的內存保護機制,自從XP和Server 20003開始引進。DEP使得系統可以標記一個或多個內存頁的屬性爲不可執行,這意味着代碼不能在該內存頁中執行,這有助於緩解緩衝區溢出攻擊的危害。若是一個應用嘗試在受保護的內存頁中運行代碼,將會觸發內存訪問異常,若是應用未處理該異常,默認處理會終止該進程。git
ASLR,Address Space layout randomization
加載地址隨機化機制,github
開啓方式:VS開發環境中的連接器下的高級選項中能夠設置映像隨機化、堆棧隨機化、PEB和TEB隨機化等。shell
GS機制,緩衝區安全檢查,開啓此功能,編譯器會爲每一個函數調用的入口增長額外的隨機數(該隨機數稱爲canary),它位於EBP以前,同時在.data內存區存放該隨機數副本。當函數棧發生溢出時,它會被覆蓋,函數在返回以前會比較.data區中副本的值和棧幀真實值,若是二者不相等,則觸發異常處理流程。windows
開啓方式:VS開發環境中的C/C++下的代碼生成中的開啓緩衝區安全檢查。數組
NX機制,No-Execute,同Windows上的DEP功能相似,將數據所在內存頁標誌爲不可執行,當程序溢出轉入shellcode時,會嘗試在數據頁上執行指令,此時CPU會拋出異常。安全
關閉NX機制,編譯時增長 -z execstack
開啓NX機制,編譯時增長 -z noexecstack(默認開啓)cookie
系統級別關閉PIE echo 0 > /proc/sys/kernel/randomize_va_space
開啓PIE的工做模式1,在編譯時增長 -fpie -pie
開啓PIE的工做模式2,在編譯時增長 -fPIE -pie(默認開啓)
系統級別的PIE決定程序運行棧和堆段的地址隨機化。
編譯器的PIE選項決定程序靜態段(bss、data、text)地址隨機化。dom
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來查看。