C 格式字符串漏洞和输入字符串

C 格式字符串漏洞和输入字符串,c,string,security,exploit,format-string,C,String,Security,Exploit,Format String,假设我有以下程序: #include <stdio.h> #include <string.h> #include <stdlib.h> int main (int argc, char **argv) { char buf [100]; snprintf ( buf, sizeof buf, argv [1] ) ; buf [ sizeof buf -1 ] = 0; printf ( "%s \n" , buf )

假设我有以下程序:

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>

int main (int argc, char **argv)
{
    char buf [100];
    snprintf ( buf, sizeof buf, argv [1] ) ;
    buf [ sizeof buf -1 ] = 0;
    printf ( "%s \n" , buf ) ;
    return 0 ;
}
我可以看到堆栈值,这意味着它受到格式字符串漏洞的影响

现在,让我们稍微修改一下上面的代码:

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>

int main (int argc, char **argv)
{
    char buf [100];
    printf ( "%s \n" , argv[1] ) ;
    return 0 ;
}
为什么会发生这种情况,与第一个示例相比发生了什么变化

另外,在第一个例子中,Prtf中的%s不应该把BUF看作一个字符串吗?为什么这样的代码仍然受到格式字符串漏洞的影响

snprintf ( buf, sizeof buf, argv [1] ) ;
您刚刚滥用了snprintf,因为您没有传递与格式字符串匹配的参数
%p%p

所以你有一个UB

例如,您应该(使用相同的格式字符串)


如果希望第一个代码段的输出与第二个代码段匹配,只需使用与
printf
相同的格式说明符即可,即:

snprintf ( buf, sizeof buf, "%s", argv [1] );
                            ^^^^
在这种情况下,
argv[1]
字符串不会被视为某些其他参数的格式模板,您只需将
%p%p
写入
buf

您是否打算改为复制字符串?我这样问是因为
snprintf
自动终止缓冲区,您不需要手动设置空终止符(这是:


您正在询问有关格式字符串漏洞的问题。每当用户提供的字符串用作任何
*scanf
*printf
函数的格式时,就会出现格式字符串漏洞

在第一个片段中,该漏洞与
snprintf
有关。在第二个片段中,
printf
具有格式字符串
“%s”
。它不是由用户提供的,因此没有漏洞。试一试

printf(buf);

%p%p%p
太蹩脚了,试试
%n%n%n
那些多余的空格看起来很糟糕。他们让人更难理解发生了什么事情。嗯,你完全去掉了脆弱的部分,一方面。
snprintf ( buf, sizeof buf, argv [1], argv[0], buff, "Hello, Show where string literals are stored" ) ;
snprintf ( buf, sizeof buf, "%s", argv [1] );
                            ^^^^
strncpy ( buf, argv [1], sizeof buf );
buf [ sizeof buf - 1 ] = 0;
printf(buf);