在论文Exploiting Format String Vulnerabilities中,作者提供了以下代码示例,其中input
是未经过滤的用户输入。
char outbuf[512];
char buffer[512];
sprintf (buffer, "ERR Wrong command: %400s", input);
sprintf (outbuf, buffer);
然后他们通过使用特殊格式字符串作为输入来解释它们可以绕过%400s
限制:
"%497d\x3c\xd3\xff\xbf<nops><shellcode>"
这将创建一个长度为479个字符的字符串。但是,我无法找到%479d
如何绕过%400s
限制的解释。这个输入如何使sprintf写一个长度超过400个字符的字符串?
答案 0 :(得分:2)
第二个sprintf()
溢出outbuf
,因为它使用第一个sprintf()
生成的格式字符串,并放置&#34;%497d&#34;在该字符串中,它会打印一个497-char宽的整数字段(用空格填充以获得整个宽度)。这与该字符串的其余部分一起将超过512-char outbuf
缓冲区大小。它还会尝试读取一个实际上没有传递给函数的整数参数(第二个sprintf()
)。
答案 1 :(得分:0)
问题是如果input
包含%
个标记,则buffer
将包含%
个标记(在第一个sprintf()
之后),然后使用第二个sprintf()
,'格式字符串'为buffer
,其中的%
标记将被解释,即使没有插入outbuf
的参数也是如此。为了避免这个问题:
snprintf(outbuf, sizeof(outbuf), "%s", buffer);
或
strcpy(outbuf, buffer);
在这种情况下,snprintf()
是过度的,但它正在将机制剥离到基础。