为什么 printf(inputString) 是一个安全漏洞?

Why is printf(inputString) a security hole?

我在 Quora 上阅读一个答案时遇到了一些简单的问题:

char* inputString;
printf(inputString);

是一个安全漏洞。

我假设 inputString 不是简单地未初始化,而是在两个语句之间使用一些外部输入进行了初始化。

究竟这是一个安全漏洞吗?

Quora 上的原始答案在这里:

If C and C++ give the best performance, why do we still code in other languages?

但它没有为此声明提供额外的上下文。

我假设输入字符串是你从用户那里得到的字符串,而不仅仅是一个未初始化的值。

问题是用户可以

  • 使程序崩溃:printf ("%s%s%s%s%s%s%s%s%s%s%s%s")
  • 查看堆栈:printf ("%08x %08x %08x %08x %08x\n");
  • 查看任意位置的内存,
  • 甚至可以将整数写入进程内存中的几乎任何位置。

这导致攻击者能够:

  • 覆盖控制访问权限的重要程序标志
  • 覆盖 return 堆栈上的地址、函数指针等

都解释的很好here

char* inputSting; 
printf(inputSting);

打印出未初始化的字符串是未定义的行为。未定义行为的影响范围从打印垃圾值到段错误和其他不良行为。这种不可预测的模式可以被利用,从而危及安全。

但更重要的是,没有人会写这个,因为它除了冒段错误的风险外没有任何意义。

不只是安全问题,根本就不行,因为指针没有初始化。在这种情况下,使程序崩溃 = 不再 运行 可能是一个(安全)问题,具体取决于程序的作用和运行的上下文。

我假设你的意思是你有一个正确的字符串。在这种情况下,如果字符串是由某些外部输入(用户等)提供的,则可能会有(意外的)占位符,如 %s 等,而 printf 的其余部分则需要例如。广告。对于此示例(%s 而不是 %d),它不会打印整数,而是开始打印所有内存内容,直到某个 0 字节,然后可能会给出存储在 int 字节之后的一些秘密信息。

类似的东西,即。由于错误的未经检查的用户输入而给出太多字节,例如发生。在不久前已知的 "Heartbleed" 错误中,was/is 是一个相当大的全球性问题。 ...第一个 printf 参数应该是固定的,而不是来自任何变量。

其他占位符组合也是可能的,从而导致广泛的可能影响(包括在 CPU 中生成错误的浮点信号,这可能会导致更严重的问题,具体取决于体系结构,etc.etc.)