C 中的 printf 和 %s

printf and %s in C

我了解到此代码段应该存在缓冲区溢出漏洞问题:

printf("File %s", my_file_name);
printf("File %s"); 

但是,我不明白为什么它被认为是有风险的。任何人都可以阐明这一点吗?

第一次通话没问题。 (当您使用用户提供的格式字符串时存在问题,如 printf(s),其中 s 受用户影响。这里您使用硬编码的格式字符串 "File %s",它不易受攻击。字符串 my_file_name 的内容将被视为常规 C 字符串并仅被复制到标准输出。当然它必须以 null 终止,并且如果输出被重定向到其他内容,则可能会产生副作用,但这不是 printf 问题。)

第二次调用只是未定义的行为,因为格式字符串 (0) 之后的参数数量与格式字符串要求的参数数量 (1) 不匹配。

下面的代码将my_file_name的内容输出到标准输出:

printf("File %s", my_file_name);

如果从恶意源接收到 my_file_name 并且程序输出到终端,恶意源可能会在 my_file_name 中放置转义序列,告诉终端执行非琐碎的任务,例如通过标准输入发回终端内容。很难但可以想象,攻击者可能会从此类攻击中获取有用的信息,甚至试图通过执行命令来破坏数据,就好像它们是由用户键入的一样。

当然,第二次调用会调用未定义的行为,因为您没有将有效的字符串指针作为第二个参数传递给 printf

上述情况可能不是您所说的缓冲区溢出漏洞printf 代码本身不存在此类漏洞,但如果您的代码中其他地方存在缓冲区溢出漏洞,并且可以通过此溢出修补实际格式字符串,攻击者可以利用 printf 的功能,尤其是 %n 格式,可以将任何值插入程序内存中的几乎任何位置。这是在 Microsoft 安全文件中公开的在 printf_s 中删除 %n 的理由。