栈溢出(stack-based buffer overflows)算是安全界常见的漏洞。一方面因为程序员的疏忽,使用了 strcpy、sprintf 等不安全的函数,增加了栈溢出漏洞的可能。另一方面,因为栈上保存了函数的返回地址等信息,因此如果攻击者能任意覆盖栈上的数据,通常情况下就意味着他能修改程序的执行流程,从而造成更大的破坏。这种攻击方法就是栈溢出攻击(stack smashing attacks)。 栈是从高地址到低地址增长的。
栈溢出攻击的原因是由于程序中缺少错误检测,另外对缓冲区的潜在操作(比如字符串的复制)都是从内存低址到高址,而函数调用的返回地址往往就在缓冲区的上方(当前栈底),这为我们覆盖返回地址提供了条件。下面是stack smashing attacks示意图:
下面是一个存在栈溢出的DEMO:
#include <stdio.h> #include <string.h>
int bof(FILE *badfile){ char buffer[20]; fread(buffer, sizeof(char), 100, badfile); return 1; }
int main(){ FILE *badfile; badfile = fopen("badfile", "r"); bof(badfile);
printf("Returned Properly\n"); fclose(badfile); return 0; } DEMO的逻辑很简单,就是从badfile文件中读取最长100字节的数据,然而buffer的长度只有20字节,所以这里是有可能发现栈溢出的。
下面是在cygwin的环境下编译出来的汇编代码(我已经把一些对逻辑理解无关的细节去掉):_main: pushl