【问题标题】:Format string vulnerability and input strings格式化字符串漏洞和输入字符串
【发布时间】:2017-08-25 23:35:44
【问题描述】:

假设我有以下程序:

#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 视为字符串吗?为什么这样的代码仍然受到格式字符串漏洞的影响?

【问题讨论】:

  • %p%p%p 很蹩脚,试试%n%n%n%n
  • 那些多余的空间看起来很糟糕。他们使阅读正在发生的事情变得更难
  • 好吧,你完全删除了易受攻击的部分,一方面。

标签: c string security exploit format-string


【解决方案1】:

如果您希望第一个 sn-p 的输出与第二个匹配,则只需使用与 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;

【讨论】:

    【解决方案2】:

    您在询问格式字符串漏洞。每当用户提供的字符串被用作 any *scanf*printf 函数的格式时,就会出现格式字符串漏洞。

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

    printf(buf);
    

    【讨论】:

      【解决方案3】:
      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" ) ;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-31
        • 1970-01-01
        • 2014-11-22
        • 2020-10-26
        • 2018-05-02
        相关资源
        最近更新 更多