缓冲区是用于数据存储的临时区域。当程序或系统进程放置了更多的数据(而不是最初分配用于存储的数据)时,多余的数据就会溢出。这会导致某些数据泄漏到其他缓冲区中,从而损坏或覆盖它们所保存的任何数据。
在缓冲区溢出攻击中,额外的数据有时会包含针对黑客或恶意用户打算采取的措施的特定说明;例如,数据可能触发响应,从而损坏文件,更改数据或公开私人信息。
攻击者将使用缓冲区溢出攻击来利用正在等待用户输入的程序。缓冲区溢出有两种类型:基于堆栈的溢出和基于堆的溢出。基于堆的方法难以执行,并且是两者中最不常见的一种,它通过泛滥为程序保留的内存空间来攻击应用程序。基于堆栈的缓冲区溢出(在攻击者中更为常见)通过使用所谓的堆栈(用于存储用户输入的内存空间)来利用应用程序和程序。
让我们研究一些基于C的实际程序示例,这些示例显示了这种情况的危险。
在示例中,我们没有实现任何恶意代码注入,只是为了表明缓冲区可能溢出。现代的编译器通常在编译/链接时提供溢出检查选项,但是在运行时,如果没有任何其他保护机制(例如,使用异常处理)来检查此问题是非常困难的。
// A C program to demonstrate buffer overflow
#include
#include
#include
int main(int argc, char *argv[])
{
// Reserve 5 byte of buffer plus the terminating NULL.
// should allocate 8 bytes = 2 double words,
// To overflow, need more than 8 bytes...
char buffer[5]; // If more than 8 characters input
// by user, there will be access
// violation, segmentation fault
// a prompt how to execute the program...
if (argc < 2)
{
printf("strcpy() NOT executed....\n");
printf("Syntax: %s \n", argv[0]);
exit(0);
}
// copy the user input to mybuffer, without any
// bound checking a secure version is srtcpy_s()
strcpy(buffer, argv[1]);
printf("buffer content= %s\n", buffer);
// you may want to try strcpy_s()
printf("strcpy() executed...\n");
return 0;
}
在Linux上编译该程序,并使用命令outpute_file INPUT进行输出以供输出
Input : 12345678 (8 bytes), the program run smoothly.
Input : 123456789 (9 bytes)
"Segmentation fault" message will be displayed and the program terminates.
存在此漏洞的原因是,如果用户输入(argv [1])大于8个字节,则缓冲区可能会溢出。为什么是8个字节?对于32位(4字节)系统,我们必须填充一个双字(32位)存储器。字符(字符)大小为1个字节,因此,如果我们请求5个字节的缓冲区,系统将分配2个双字(8个字节)。这就是为什么当您输入8个以上的字节时; mybuffer将溢出
确实存在技术上较不易受攻击的类似标准函数,例如strncpy(),strncat()和memcpy()。但是这些函数的问题在于,声明缓冲区(而不是编译器)的大小是程序员的责任。
每个C / C++编码人员或编程人员在进行编码之前必须知道缓冲区溢出问题。在大多数情况下,由于缓冲区溢出,可以利用许多生成的错误。
参考
维基百科
缓冲区溢出
C++ BufferOverflow