缓冲区溢出会覆盖局部变量

时间:2014-01-28 03:08:28

标签: c buffer-overflow

我正在进行缓冲区溢出练习,其中给出了源代码。练习允许您更改您提供给程序的参数向量的数量,以便您可以解决null问题,从而轻松实现。

然而,该练习还提到可以仅使用1个参数向量来破坏此代码。我很想知道如何做到这一点。任何关于如何处理这个问题的想法将不胜感激。

这里的问题是需要覆盖长度以便发生溢出并且损坏返回地址。据我所知,你不能在字符串中真正使用NULL,因为它们是通过execve参数传递的。所以长度最终是一个非常大的数字,因为你必须写一些非零数字导致整个堆栈繁荣,这与返回地址的情况相同。我错过了一些明显的东西吗是否需要利用strlen。我看到一些对有符号数的算术溢出的引用,但我不确定转动局部变量是否有效。

代码发布在下面并返回一个main函数,然后结束程序并在一个小端系统上运行并关闭所有堆栈保护,因为这是对infosec的介绍性练习:

int TrickyOverflowSeq ( char *in )
{
    char       to_be_exploited[128];
    int        c;
    int        limit;

    limit = strlen(in);
    if (limit > 144)
        limit = 144;

    for (c = 0; c <= limit; c++)
            to_be_exploited[c] = in[c];

    return(0);
}

3 个答案:

答案 0 :(得分:1)

我不知道arg来自何处,但由于您的缓冲区仅为128字节,并且您将最大长度限制为144,因此您只需要传入一个字符串复制into_be_exploited时,超过128个字节会导致缓冲区溢出。任何恶意代码都将位于从129位置到144的输入缓冲区中。

这是否能正确设置返回不同位置取决于很多因素。

答案 1 :(得分:0)

  

然而,该练习还提到可以仅使用1个参数向量来破坏此代码。我很想知道如何做到这一点。

...

  

这里的问题是需要覆盖长度以便发生溢出并且返回地址会受到损害。

对我来说这似乎很简单。如果sizeof(int) == 8,那么这个神奇的数字144是有意义的,如果你正在为64位构建它,那就是它。

因此,假设to_be_exploited位于climit之前的堆栈布局,您只需在从偏移量136开始的字节中传入一个带有垃圾的非常长的字符串(即{ {1}}),然后在以偏移量144开头的字节中精心设计垃圾。这将从该字节开始覆盖128 + sizeof(int),从而禁用长度检查。然后精心制作的垃圾将覆盖返回地址。

您可以将几乎所有内容放入从偏移量136开始的8个字节中,并让它们生成一个足以禁用安全检查的数字。只要确保你没有以负数结尾。例如,字符串“HAHAHAHA”将作为整数评估为5206522089439316033.此数字大于144 ...实际上,它太大,因为您希望此函数在复制字符串后停止复制。所以你只需要确定你的攻击字符串实际存在多长时间,并将该长度的正确字节放入该位置,攻击将被复制。

请注意,C中的普通字符串处理函数使用NUL字节作为终结符,并停止复制。这个功能不这样做;它只信任limit。所以你可以在输入字符串中放入任何你想要的垃圾来利用这个功能。但是,如果正常的C库函数需要复制输入数据,则最终可能需要避免使用NUL字节。

当然,没有人应该把这些愚蠢的代码投入生产。

编辑:我匆匆写了上面的内容。现在我有更多时间,我重新阅读你的问题,我想我更清楚你想要解释的内容。

你想知道一个字符串如何能够正确地删除limit正确的长度,而不会让limit剁掉它。这在大端计算机上是不可能的,但在小端计算机上完全可能。

在小端计算机上,第一个字节是最低有效字节。请参阅维基百科条目:

http://en.wikipedia.org/wiki/Endianness

任何非常大的数字必须在其最重要的字节中为零。在大端计算机上,这意味着前几个字节都将为零,将像NUL一样,并且会导致strlen()在函数崩溃strlen()之前切断字符串。但是,在小端计算机上,要复制的重要字节都将出现在NUL字节之前。

在互联网发展初期,大端计算机(通常从Sun Microsystems购买)运行Internet服务器应用程序很常见。目前,商品x86服务器硬件最常见,x86是little-endian。实际上,任何部署像limit函数这样的可利用代码的人都会被取消。

如果您认为这个答案不够彻底,请发表评论,说明您认为我需要更好地涵盖哪些部分,我会更新答案。

答案 2 :(得分:0)

我知道这是一个很老的帖子,但是我偶然发现了您的问题,因为我发现自己处在与您在帖子和评论中所问的问题完全相同的情况下。

几分钟后,我解决了这个问题。我不知道在这里应该“破坏”多少,因为AFAIK在许多计算机安全课程中都是一个典型的问题。但是我可以说,确实可以仅使用一个参数以及两个环境变量来实现该解决方案。附加提示:环境变量存储在函数参数后的 栈中(如中比函数参数更高的地址)。