关于缓冲区溢出

时间:2010-04-24 11:15:22

标签: c stack-overflow buffer-overflow

我是道德黑客世界的新手,其中一个最重要的事情是堆栈溢出,无论如何我编写了一个易受攻击的C程序,它有一个char name [400]语句,当我尝试运行程序时401A它没有溢出,但是我所遵循的这本书说它必须溢出而且逻辑意义上是这样说的,那么什么是错的???

4 个答案:

答案 0 :(得分:5)

如果您已定义缓冲区:

char buf[400];

并在其中写入401个字节,缓冲区已溢出。其余的,取决于代码的结构:

  • 缓冲区如何分配(静态,动态,在堆栈上)
  • 内存中前后的内容
  • 您的架构的调用约定和ABI(在堆栈缓冲区的情况下)
  • 更多......

事情比他们看起来更复杂。引用Wikipedia

  

在计算机安全和编程方面,   缓冲区溢出或缓冲区溢出,   是一个过程存储的异常   数据在内存之外的缓冲区中   程序员留出来。该   额外的数据会覆盖相邻的内存,   可能包含其他数据,   包括程序变量和   程序流程控制数据。这可能   导致程序行为不稳定,   包括内存访问错误,   结果不正确,程序终止   (崩溃),或违反系统   安全

请注意在此引用的词的可以的多个实例。所有这一切的可能的发生,它的可以的不是。同样,这取决于其他因素。

答案 1 :(得分:3)

C不检查缓冲区溢出(溢出缓冲区是一种未定义的行为)。通常系统只允许你(和黑客)在缓冲区之外写入,这就是缓冲区溢出易受攻击的原因

例如,如果代码是

char name[400];
char secret_password[400];
...

内存可以布局为

[John             ][12345                 ]
 name               secret_password

现在,如果您将A写入后跟name的NULL,则额外的A\0将写入secret_password,这基本上会更改您的行李箱组合中的密码只是“A”:

[AAAAAAAAA...AAAAA][A␀345                ]
 name               secret_password

答案 2 :(得分:2)

这是C中的good example,显示了缓冲区溢出如何用于执行任意代码。其目标是找到一个输入字符串,它将覆盖返回地址,从而导致执行目标函数。

为了更好地解释缓冲区溢出,我建议Writing Secure Code 2nd Edition的第5章。

有关缓冲区溢出的其他好消息:

答案 3 :(得分:2)

Stackoverflow和bufferoverflow是不同的概念 的#1:
程序堆栈的大小是静态的,它永远不会在运行时更改。由于无法知道堆栈在运行时需要多少内存,因此保留了合理的大内存块。然而,有些程序通过调用rekursive函数来实现这一点 函数调用保留尽可能多的空间,以便将lokal变量存储在堆栈中,并在它退出后释放内存。递归函数将在每次输入时保留新内存,并在退出后释放。如果递归由于编程错误而永远不会结束,则堆栈上的内存越来越多,直到堆栈已满为止 尝试在完整堆栈上保留内存将导致错误,即堆栈溢出 示例代码:

volatile bool args = false;
int myoverflow(int i){
  int a[500];   
if(args)
   return a[i%500];
else
   return myoverflow(i+1);
}

这应该溢出堆栈。每次进入函数时它都会保留500 * sizeof(int)。

<强>缓冲区溢出: 你有两个变量,一个数组a和一个数组b。 a可以容纳4个元素,b可以容纳2个元素。 现在你将5个元素写入a,第5个元素落入b。
例如:

void main(int ,char**)
{
  int a[4];
  int b[2];
  a[5] = 22;
  std::cout<<b[0];
}

这应该打印22.它将在a之外写入b。

使用的内存中

注意:我的示例函数都不能保证工作,编译器可以自由地优化函数调用并根据需要安排堆栈中使用的内存。它甚至可能在访问内存超出阵列a的界限时打印编译错误。