【笔记】内存溢出

内存溢出可能有栈溢出(栈内存不够分配),缓冲区溢出(接受用户输入、调用方法返回时,用的缓冲区不够分配),堆溢出(就是对内存不够分配,对象无法创建,无法new)

 

可能会造成安全漏洞:https://www.zhihu.com/question/40560123 杨博的答案

  举例:

    从不受自己控制的来源获取数据,同时又没有对来源的数据大小做出限制,且在程序中毫无检查和校验的情况下使用(调用可能表面上很正确的方法和对象/API),就会造成“栈溢出”、“缓冲区溢出”、“堆溢出”。

作者:杨博
链接:https://www.zhihu.com/question/40560123/answer/129719625
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在C/C++中,无论栈溢出还是缓冲区溢出都是安全漏洞的温床。

比如说C/C++标准库有个strcpy,会一直复制内存,直到遇到\0。比如如果你用C++写了一个游戏服务器,其中读取客户端网络包的代码写成这样:

const int MAX_LENGTH = 16;
bool is_administrator = false;
char destination[MAX_LENGTH];

std::string source = read_string_from_client();
strcpy(destination, source.c_str());

 

那么如果黑客构造出的source长于16字节,那么就会修改到destination之外的内存。很多平台的栈变量是跟按地址顺序倒着分配的。所以destination溢出以后会修改先前定义的变量。比如黑客可以用这个办法把is_administrator修改成true。
这种情况就是缓冲区溢出攻击。

假如黑客黑掉服务器之后,把你的服务端程序偷出来开私服。由于私服泛滥,游戏失败了。于是你的新游戏决定抛弃了C++,改用C99标准的C语言。这次你这样写:

int length = read_int_from_client();
char buffer[length];
int data = read_int_from_client();

这里会在栈上分配length字节的空间,然后再往栈顶放上一个data。当length很大时,会把data挤到栈空间之外。这种情况下,假如编译器生成的代码没有越界检查的话,那么黑客只要用客户端发送特定的length和data组合,就能够改写服务器的任意内存。黑客通常会修改服务器代码的机器码,比如注入一些jmp指令,让线程跳到黑客想执行的函数。

那么这一次你又被“栈溢出”攻击黑掉了服务器。

posted @ 2018-08-30 18:45  彭玉松  阅读(208)  评论(0编辑  收藏  举报