2)缓冲区溢出攻击原理
缓冲区溢出是一种非常普遍也非常危险的漏洞,广泛存在于各种操作系统、应用软件中。漏洞的原因是由于程序员对数据没有进行严格的校验,攻击者可以通过向程序的缓冲区写入超过预定长度的数据j从而破坏程序的堆栈,导致程序执行流程的改变
#inclucle <stdio.h>
int main() (
char name[8];
printf(’’Please inpur your name:¨); gets(name);
printf(”you name is:%s!”, name); return 0:
)
这段程序的功能是显示输入的用户名称。在程序中,用于存放用户输入名称的变量name长度定义为8位,由于程序缺少必要的输入长度校验,当用户的输入值超过8位时,
printf(”you name is:%s!",name)执行时会导致一个缓存溢出。例如输入用户输入姓名为
“aaaaaaaaaaaaaaaaaaaaaaaa”时,由于输入值超过name定义的长度(程序申请缓冲区),当
程序将用户输入值保存到name的地址空间时,会继续向内存后续地址空间写入其余输入内容,进而覆盖了程序栈中存储的返回地址( EIP),如下图所示。
内存底部 内存顶部
正常状态下的堆栈
name XXX EIP XXX
[cispcisp] [ ] [ ] [ ]
name XXX既P XXX
[aaaaaaaa] [aaaa] [aaaa] [aaaa] ‘
溢出状态下的堆栈
堆栈顶部 堆栈底部
图3-21缓冲区溢出堆栈状态
程序在需要调用返回地址时,把EIP中存储的“aaaa”的ASCⅡ码Ox61616161作为下一条指令地址,CPU会试图执行Ox61616161处的指令,而由于该内存并非运行程序所能访问,因此这个操作会被系统拒绝,因此产生错误。如图所示。
如果攻击者输入的内容是经过精确定义的,覆盖了EIP原有的地址,使得程序跳转攻击者覆盖进去的地址,而该地址处执行预先放置一段攻击代码,那么攻击者就可以执行这段攻击代码从而获得系统控制权或者执行其他攻击操作。