1

我是道德黑客世界的新手,最重要的事情之一是堆栈溢出,无论如何我编写了一个有 char name [400] 语句的易受攻击的 C 程序,当我尝试使用 401A 运行程序时它没有'不会溢出,但是我正在关注的书说它必须溢出并且逻辑意义上说是这样,所以出了什么问题???

4

4 回答 4

5

如果你定义了一个缓冲区:

char buf[400];

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

  • 缓冲区是如何分配的(静态、动态、在堆栈上)
  • 在记忆中之前和之后发生了什么
  • 您的架构的调用约定和 ABI(如果是堆栈缓冲区)
  • 多一点...

事情比看起来更复杂。引用维基百科

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

请注意此引用中可能出现的多个实例。所有这一切都可能发生,也可能不会发生。同样,这取决于其他因素。

于 2010-04-24T11:22:59.723 回答
3

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

例如,如果代码是

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

内存可以布局为

[John             ][12345                 ]
 name               secret_password

现在,如果您将 401A后跟 NULL 写入name,则额外A\0内容将写入secret_password,这基本上将密码从您的行李组合更改为“A”:

[AAAAAAAAA...AAAAA][A␀345                ]
 name               secret_password
于 2010-04-24T11:27:22.853 回答
2

这是 C 语言中的一个很好的示例,展示了如何使用缓冲区溢出来执行任意代码。它的目标是找到一个输入字符串,该字符串将覆盖导致目标函数执行的返回地址。

对于缓冲区溢出的一个很好的解释,我推荐编写安全代码第 2 版的第 5 章。

有关缓冲区溢出的其他有用信息:

于 2010-04-24T11:59:59.180 回答
2

Stackoverflow 和 bufferoverflow 是不同的概念。
Stackoverflow:
程序堆栈的大小是静态的,它在运行时永远不会改变。由于无法知道您的堆栈在运行时需要多少内存,因此保留了一个合理的大内存块。然而,一些程序通过调用递归函数来执行此操作。
函数调用保留了在堆栈上存储本地变量所需的空间,并在退出后释放内存。递归函数将在每次进入时保留新内存,并在退出时释放它。如果递归由于编程错误而永远不会结束,则在堆栈上保留越来越多的内存,直到堆栈满为止。
尝试在完整堆栈上保留内存将导致错误,即 stackoverflow。
示例代码:

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) 。

Bufferoverflow: 你有两个变量,一个数组 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 越界访问内存时打印编译错误。

于 2010-04-24T12:07:51.680 回答