ASLR,PIE,PIC的相似處及區別
之前一直都以為ASLR和PIE是相同的東西,看了蒸米大佬的一步一步學rop和檢視很多文章後,才意識到其中的區別的,記下筆記方便複習。只有把這幾個機制弄清楚了,才能知道哪些地址是動的,哪些是不動的,寫exp的時候才能寫出通解。
百度百科關於ASLR(Address space layout randomization)的說法如下:
aslr是一種針對緩衝區溢位的安全保護技術,通過對堆、棧、共享庫對映等線性區佈局的隨機化,通過增加攻擊者預測目的地址的難度,防止攻擊者直接定位攻擊程式碼位置,達到阻止溢位攻擊的目的的一種技術。
檢視當前系統ASLR的開啟情況:
cat /proc/sys/kernel/randomize_va_space
如果是0,代表ASLR關閉,
如果是1,是部分隨機化,棧,共享庫,vdso隨機化。
如果是2,代表在1的基礎上,堆也被隨機化了。
開啟ASLR後,每次啟動程式,libc.so的基址就會發生變化:
將其值修改為2,然後檢視動態庫基址:
但是ASLR並不會隨機化自身程式的程式碼段和資料段。
(圖片來自蒸米大佬的一步一步學rop http://www.vuln.cn/6645 )
也就是說程式的載入還是從低地址0x08048000開始的。ASLR影響的只是堆,棧,和動態庫的基址,並不會影響程式載入的基址。
想要影響程式本身載入的基址,就需要開啟PIE(position Independent executable ),開啟PIE後,將本身程式也標記成為一種特殊的.so檔案,所以依賴於ASLR的開啟。簡而言之就是開啟PIE就必須開啟ASLR。
PIC(position Independent code)就是位置無關程式碼,和動態庫有關(有關靜態連結和動態連結可以看《深入理解計算機系統》這本書)。
之前以為PIC開啟後,每次啟動程式後,動態庫的基址本來就是變化,其實在不開ASLR的情況下,同一臺機器上libc.so載入的基址是相同的,關機後再測試依然是相同的,不同機器上libc.so載入的基址才是不同的。
以同一臺機器為例:
不同虛擬機器為例:
動態庫載入的基址都是不同的。(libc.so的版本都是相同的)