我是道德黑客世界的新手,其中一个最重要的事情是堆栈溢出,无论如何我编写了一个易受攻击的C程序,它有一个char name [400]语句,当我尝试运行程序时401A它没有溢出,但是我所遵循的这本书说它必须溢出而且逻辑意义上是这样说的,那么什么是错的???
答案 0 :(得分:5)
如果您已定义缓冲区:
char buf[400];
并在其中写入401个字节,缓冲区已溢出。其余的,取决于代码的结构:
事情比他们看起来更复杂。引用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的界限时打印编译错误。