【问题标题】:Format String vulnerability格式化字符串漏洞
【发布时间】:2012-03-03 19:04:18
【问题描述】:

我有简单的 C 程序:

char user_input[100];
scanf("%s", user_input);
printf(user_input);

据我了解,这代表安全漏洞;例如输入一堆 %x 将打印出堆栈的内容。

但是如何打印一个选定的内存位置呢?

我读到了:

\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s|

应该从this paper 转储位置0x08480110 的内存内容。但相反,它正在将接下来的 4 个字节打印到堆栈上的格式字符串中。我正在尝试了解原因。

【问题讨论】:

  • 这是一个森林问题,输入超过 99 个字符会引发缓冲区溢出。 Little Bobby Tables 不清理输入的故事。

标签: c string security scanf


【解决方案1】:

格式字符串本身将在堆栈中(因为您已将user_input 声明为局部变量)。因此,如果您将堆栈走得足够远(这是%08x 强制printf 执行的操作),那么您最终将到达格式字符串的开头。 %s 告诉 printf 从堆栈中读取地址,然后打印在该位置找到的字符串。所以它读取格式字符串的前 4/8 个字节,并将其用作地址。

当然,要使其工作,您需要确切地知道要读取堆栈多远才能命中格式字符串。所以你可能需要调整%08x的数量。

此外,在运行时输入\x10 的用户与源代码中包含\x10 的字符串文字不同...

【讨论】:

  • 内存中的格式字符串不低于 user_input 吗?另外,我知道 %x “遍历堆栈”,有没有办法不打印堆栈的全部内容,即一种将堆栈向上移动到格式字符串的方法,该格式字符串将使用前 4 个字节作为地址它必须从堆栈中读取,但是,没有打印出两者之间的所有内容?
  • @Pi_:这取决于。在 x86 上,堆栈通常向下增长(因此printf 的堆栈帧将位于比调用者的堆栈帧更低的地址)。
  • 注意:我发现输入 "%n$x" 其中 n 是一个整数正在经历前 n-1 次迭代而没有打印出结果(即它正在弹出 n-1 次迭代并直接进入n的迭代)
【解决方案2】:

这在Exploiting Format String Vulnerabilities.中有详细解释

如果您想要图片,请参阅这些lecture notes 的第 4.4 节。

【讨论】:

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