看看這個脆弱的片段:什麼導致這種格式字符串攻擊?
int main(int argc, char **argv) {
printf(argv[1], "bla");
return 0;
}
沒有優化的編譯它導致
./test "asd"
asd
./test "asd %s"
asd bla
./test "asd %0\$s"
asd %0$s
./test "asd %45\$s"
asd XDG_VTNR=7 <-- What the...
嗯,其實它似乎像 「%(數量)\ $ S」 試圖解釋(數字)作爲一個字符串的第三個參數,向上看堆棧,並且我遇到了我的環境變量。在任何地方使用這種格式字符串,特別是使用奇怪的「\ $」?我找不到任何參考。
最後,編譯與優化啓用它會導致:
*** invalid %N$ use detected ***
asd zsh: abort ./test "asd %46\$s"
我從來沒見過這樣的錯誤。它從何而來?
(我使用的Gentoo Linux/GCC 4.8.2/glibc的2.18)
我還在調試時爲什麼在我測試的程序的輸出中出現字符'X'(而不是'argv [2]'中的最後一個字符)。它與argv [2](緊接着'argv [2]''終止'NUL'字符後面]連續出現。 '(gdb)p sp1 = argv [2] + 4' =>'$ 11 = 0x7fffffffe4a7「XDG_VTNR = 1」'。所以它顯然是在只讀部分。 –
有趣的是,我發現'argv'的是,如果我檢查與'argv [1]'('argv [1] + strlen(argv [1])'')連續的內存,它確實是'argv [2]',但'argv [2]'(最後一個參數)是一個環境變量'「XDG_VTNR = 1」'的連續內存與argv [3]不同,它顯然是一個空指針終止列表。 'argv [4]',* whatever *,確實包含了這個內存,並在argv結束後繼續下去,顯示出大量的環境變量。 –