c++ - 什么是缓冲区溢出,如何导致?

标签 c++ buffer-overflow fortify-source

我听说过缓冲区溢出,我想知道如何导致。

谁能给我看一个小的缓冲区溢出示例? 新的(它们的用途是什么?)

最佳答案

缓冲区溢出的经典示例:

// noone will ever have the time to type more than 64 characters...
char buf[64];
gets(buf); // let user put his name

单独的缓冲区溢出通常不是故意发生的。它最常发生是因为所谓的“一个接一个”错误。这意味着您将数组大小错误地计算了一个 - 可能是因为您忘记考虑终止空字符,或者因为其他一些东西。

但它也可以用于一些邪恶的东西。事实上,用户早就知道这个漏洞,然后插入说 70 个字符,最后一个字符包含一些特殊字节,这些字节会覆盖一些堆栈槽 - 如果用户真的很棘手,他/她会点击堆栈中的返回地址槽, 并覆盖它,因此它向前跳转到刚刚插入的缓冲区中:因为用户输入的不是他的名字,而是他之前编译并转储出来的 shell 代码。然后那个将被执行。有一些问题。例如,您必须安排在该二进制代码中不包含“\n”(因为gets 会停止读取那里)。对于其他与危险字符串函数混淆的方式,二进制零是有问题的,因为字符串函数停止复制到缓冲区。人们也使用 xor 两次相同的值来产生零,而没有明确写入零字节。

这是经典的做法。但是有一些安全 block 可以告诉我们发生了这样的事情,以及其他使堆栈不可执行的东西。但我想有比我刚才解释的更好的技巧。一些汇编程序的人现在可能会告诉你关于这方面的长篇大论:)

如何避免

总是使用带有最大长度参数的函数,如果您不能100%确定缓冲区是否真的足够大。不要玩“哦,数量不会超过5个字符”之类的游戏——它总有一天会失败。请记住,科学家曾说过一枚火箭的数量不会超过某个数量级,因为火箭永远不会那么快。但是有一天,它实际上更快了,结果是整数溢出和火箭坠毁(这是关于 Ariane 5 中的一个错误,这是历史上最昂贵的计算机错误之一)。

例如,使用 fgets 代替获取。而不是 sprintf 在合适和可用的地方使用 snprintf (或者只是 C++ 风格的东西,比如 istream 和其他东西)

关于c++ - 什么是缓冲区溢出,如何导致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/574159/

相关文章:

c++ - C++中如何遍历栈?

c++ - 为什么不使用std::move将std::unique_ptr复制到另一个?

c - 插入和改变 %esp 帧指针

c - 缓冲区溢出漏洞实验室问题

c - GCC如何检测堆栈缓冲区溢出

c++ - ios_base::sync_with_stdio(false) 在来自标准输入的两个输入之间不起作用

c++ - lapacke 与 boost 冲突?

c++ - c++是否存在缓冲区溢出helloworld?

c - 如何使用格式字符串错误关闭 FORTIFY_SOURCE 补丁