什么导致这种格式字符串攻击?

时间:2014-01-30 19:17:26

标签: c++ c string-formatting

看看这个易受攻击的片段:

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...

嗯,实际上好像&#34;%(数字)\ $ s&#34;尝试将(数字)参数解释为字符串,查看堆栈的上方,并且我遇到了我的环境变量。在任何地方都可以使用这种格式字符串,特别是使用好奇的&#34; \ $&#34; ?我找不到任何参考资料。

最后,通过优化进行编译会导致:

*** invalid %N$ use detected ***
asd zsh: abort      ./test "asd %46\$s"

我之前从未见过这样的错误。它来自哪里?

(我使用的是Gentoo Linux / GCC 4.8.2 / glibc 2.18)

1 个答案:

答案 0 :(得分:5)

当然,它是mentioned in the manual page,就像你期望的那样。它似乎来自Single Unix规范(即不是C99)。

它用于国际化,当你需要交换各种信息的顺序以适应翻译。该数字是参数索引:

  

还可以通过编写"%m$"而不是'%'"*m$"而不是'*'来明确指定在需要参数的每个地方采用哪个参数,其中十进制整数m表示所需参数的参数列表中的位置,从1

开始索引

所以在一个更明智的计划中,这个:

printf("%2$d %1$d", 1, 2);

打印

2 1

启用优化后,可能会使编译器对代码执行更重量级的分析,以便它可以“更多地”了解实际参数列表并生成更好的错误。

相关问题