%n在这个问题上,我正在阅读C中的格式说明符.但是当我在不同的C++编译器上尝试以下程序时,它给了我不同的输出.
为什么?是什么原因?是否存在未定义或实现定义的行为?
#include<stdio.h>
int main()
{
int c = -1;
printf("geeks for %ngeeks ", &c);
printf("%d", c);
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
geeks for geeks 10
Run Code Online (Sandbox Code Playgroud)
geeks for geeks 10
Run Code Online (Sandbox Code Playgroud)
geeks -1
Run Code Online (Sandbox Code Playgroud)
Debug assertion failed ("'n' format specifier disabled",0)
Run Code Online (Sandbox Code Playgroud)
Sha*_*our 10
正如问题所述Code Blocks,确实是正确的,但Orwell Dev C++不正确.另一方面,Visual Studio不符合要求.
cppreferences printf的C文档说:
返回此函数调用到目前为止写入的字符数.
我没有在草案标准中看到任何使这个可选的内容,C++指的是C标准printf.MSDN记录了这一点并说:
由于%n格式本质上是不安全的,因此默认情况下禁用它.如果在格式字符串中遇到%n,则调用无效参数处理程序,如参数验证中所述.要启用%n支持,请参阅_set_printf_count_output.
为什么%n格式本身就不安全?
我假设他们认为它不安全,因为安全问题,如格式字符串漏洞文档中概述的一个可能的方法来利用它.它取决于由用户输入控制的格式字符串.本文给出了以下示例:
char user_input[100];
scanf("%s", user_input);
printf(user_input);
Run Code Online (Sandbox Code Playgroud)
退休忍者链接到Bugtraq帖子,该帖子演示了这样一个错误的真实例子proftpd 1.2.0pre6:
- ftp到主机
- 登录(匿名或否)
(这应该是一行,没有空格)
ftp> ls aaaXXXX%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u u %u%u%u%u%u%u%u%u%u%u%u%u%u%653300u%n
(用连续的ascii值为0xdc,0x4f,0x07,0x08的字符替换X)
通过这种方式可以轻松完成许多其他恶意事件.由于proftpd会将用户输入数据传递给snprintf,因此参数攻击很容易.
Visual Studios方法的问题在于它破坏了可移植性.其他方法包括使用gcc使用的Wformat-security等标志,结合使用-WError可能会使其成为错误,但您可以选择此作为构建过程的一部分.
| 归档时间: |
|
| 查看次数: |
1081 次 |
| 最近记录: |