從上面可以看到有數種保護。
NX 是指 Non-Executable Stack。
這會讓 Stack 位置上的東西不可被執行,所以就算想辦法用溢位把要執行的東西弄上 Stack,也沒辦法執行。以防守(?) 的角度來說,這東西基本上不太會掉效能。
不過開了的時候,倒是可以用 Heap 來做事情。或者是覆蓋返回地址,這樣也不必用到 Stack 來執行東西。
通常會把返回地址改成 libc
的 system()
,但前提是要知道 libc
的位置在哪。如果 PIE
有開,這會更麻煩。
PIE 是指 gcc -fPIE
。這代表 ASLR (address space layout optimization)是開啟的。
在沒開的狀況下,程式中用到的各函式庫位置都是可以預測的,所以在編譯時,編譯器必須把程式編譯成 Position Independent Executable。
若開了,那代表程式中各個部分的位置(例如同時用到 libc.so
& libfoo.so
的話,那就不可預測這兩個 .so
的位置)。
可以參考 OpenBSD Papers。