在函数的栈帧中,局部变量是顺序排列的,局部变量下面紧跟着的是前栈帧EBP及函数返回地址RET。如果这些局部变量为数组,由于存在越界的漏洞,那么越界的数组元素将会覆盖相邻的局部变量,甚至覆盖前栈帧EBP及函数返回地址RET,从而造成程序的异常。
接下来演示的是,将一个有效指令地址(Attack函数的入口地址)写入fun函数的返回地址区域中,这样就可以让CPU跳转到Attack攻击代码处执行,从而达到控制程序执行流程的目的。
源程序如下
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Attack( ){
printf("Hello!:-) :-) :-)\n");
//当该函数被调用时,说明溢出攻击成功了
exit(0);
}
void fun( ){
char password[6] ="ABCDE" ;
char str[6];
FILE *fp;
if(!(fp=fopen("password.txt" ,"r"))){
exit(0);
}
fscanf(fp,"%s" ,str);
str[5]='\0';
if(strcmp(str,password)==0)
printf("OK.\n" );
else
printf("NO.\n");
}
int main( ){
fun( );
return 0;
}
首先编译运行该代码,运行效果如下
然后使用IDA打开该exe文件,找到Attack函数和fun函数的入口地址分别为004013B0和004013CE
构造一个password.txt文件,内容为aaaabbbbccccddddeeeeffffgggg
使用OD打开该exe文件,在fun函数入口处设置断点,运行发现fun函数的返回地址为0040146F,存放在0061FEFC处
随后用winHex打开password.txt,在尾部增加四个字节,内容是Attack函数的入口地址004013B0
然后OD重新打开exe文件,运行调试发现fun函数的返回地址已经变为Attack函数的入口地址004013B0
继续运行,发现确实进入了Attack函数,并打印出了里面的内容