看看这个脆弱的片段:什么导致这种格式字符串攻击?
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结束后继续下去,显示出大量的环境变量。 –