使用snprintf缓冲区溢出

时间:2012-04-11 19:55:44

标签: c buffer

这是一项任务,但我对基本理解有疑问。

易受攻击的代码:

int choc(char *arg)
{
  char buf[400];
  snprintf(buf, sizeof buf, arg);
  return 0;
}

我知道arg需要是一个格式字符串,它会用我想要执行的代码的地址覆盖返回地址。但是我在创建格式字符串时遇到了麻烦。

因此,格式字符串需要具有的内容:

  1. 返回指令的地址,我需要覆盖
  2. %x
  3. 的列表
  4. 我将在退货地址上写的价值。这将是我想要执行的代码的地址。
  5. 为了获得返回地址,我只需要查看gdb中'ret'指令的地址吧? %x的目的究竟是什么?我如何用格式字符串编码我想要执行的代码的地址?

    我做过的测试: 使用gdb我发现我的buf的地址是0xbffffba0。我生成了arg为“\ xa0 \ xfb \ xff \ xbf_%x。%x。%n”;这不应该在地址0xbffffba0的buff开头写一些值吗?但是我得到了一个段错误。我做错了什么?

    任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:2)

"\xa0\xfb\xff\xbf"不应该是buf的地址,而应该是堆栈上返回地址的位置(这是您要覆盖的值)。你必须使用gdb找到这个值。

然后,您需要在格式字符串中放入足够的%x,以便%n将从堆栈中读取该值并写入您指定的地址。您还需要使用正确的字段大小,以便%n实际上写入正确的值。

答案 1 :(得分:1)

您尝试利用的漏洞称为格式字符串漏洞。 有关此主题的进一步调查,我建议THIS链接或书籍“Hacking:剥削艺术”。

答案 2 :(得分:0)

从调试器中读取值通常是不够的。某些平台具有地址空间随机化安全功能,这些功能将导致特定对象的地址在程序调用之间不同。相反,您需要找出堆栈中存储返回地址的位置(相对于snprintf调用)并在那里覆盖它。这是特定于CPU的。您正在开发什么平台?

使用调试器,在程序集级别上逐步执行该函数的代码,并在遇到return命令之前检查堆栈。确保堆栈和返回地址看起来像您认为的那样。这应该可以为您提供问题所在的线索。此外,您可以尝试在return之前使用调试器手动修改堆栈,以验证您定位的位置实际上是返回地址。

答案 3 :(得分:-1)

答案是否定的,你不需要“回复”的地址。指令。你真正需要的是记忆中的位置,即“回归”。指令加载。看看这个图表:

http://post.queensu.ca/~trd/377/tut5/stack.html

您的目标是覆盖返回地址'。

我会继续尝试编写一个简短的程序来显示这个指针(即将到来)。

更新:我有坏消息。我也无法解决这个问题。我写过:

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

void bar()
{
    printf("Bar function\n");
}

void foo()
{
    void (**p)(void);
    asm volatile("movl %%ebp, %0\n\t" : "=r"(p) : : "%0");
    p += 1;
    *p = bar;
}

int main()
{
    foo();
    return 0;
}

导致分段错误而不在bar()中打印句子。我希望它能起作用......所以现在我和你一样困惑。任何人都可以解释为什么bar()在我的代码中没有执行?