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

时间:2017-08-25 23:35:44

标签: 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 ) ;
    return 0 ;
}

如果我编译并运行它:

gcc test.c -o test
./test %p%p%p
(nil)0x4006d00x7f67e05b7ab0

我可以看到堆栈值,这意味着它受格式字符串漏洞的影响。

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

#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 ;
}

如果我重新编译并重新运行它,漏洞就会消失:

gcc test.c -o test
./test %p%p%p
%p%p%p

为什么会发生这种情况,从第一个例子改变了什么?

此外,在第一个示例中, printf 中的%s 不应将 buf 视为字符串吗?为什么此类代码仍受格式字符串漏洞的影响?

3 个答案:

答案 0 :(得分:1)

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

snprintf ( buf, sizeof buf, "%s", argv [1] );
                            ^^^^

在这种情况下,argv[1]字符串不会被视为其他参数的格式设置模板,您只需将%p%p%p写入buf

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

strncpy ( buf, argv [1], sizeof buf );
buf [ sizeof buf - 1 ] = 0;

答案 1 :(得分:1)

您正在询问格式字符串漏洞。只要用户提供的字符串用作任何 *printfsnprintf函数的格式,就会出现格式字符串漏洞。

在第一个片段中,漏洞位于printf。在第二个片段中,"%s"的格式字符串为printf(buf); 。它不是由用户提供的,因此没有漏洞。尝试

READ

答案 2 :(得分:0)

snprintf ( buf, sizeof buf, argv [1] ) ;

您刚刚滥用了snprintf,因为您没有传递参数以匹配您的格式字符串%p%p%p

所以你只有一个UB。

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

snprintf ( buf, sizeof buf, argv [1], argv[0], buff, "Hello, Show where string literals are stored" ) ;