漏洞战争读书笔记【二】 共12
栈溢出
2.1栈溢出原理
缓冲区溢出:大缓冲区向小缓冲区复制,撑爆了小缓冲区,从而冲掉了和小缓冲区相邻内存区域的其它数据而引起的问题。
#include "stdafx.h"
#include<stdio.h>
#include<string.h>
int vulnfun(char* str)
{
char stack[10];
strcpy(stack, str);//这里造成溢出
return 0;
}
int main()
{
char* str = "AAAAAAAAAAAAAAAAAAAAAAAA"; //
vulnfun(str);
return 0;
}
简单回忆以下库函数strcpy(char* destination,const char* source):是将一个字符串复制到另一个空间地址中的函数,'\0'是停止拷贝的终止条件,同时也会将'\0'也复制到目标空间。
- char* destination----目标字符串的首地址
- const char* source---源地址:被复制的字符串的首地址,用const修饰,避免修改掉被拷贝的字符串
- 函数的返回值类型:char*:返回的是目标字符串的首地址。
函数调用过程
- 参数入栈
- 返回地址入栈
- 代码去跳转
- 栈帧调整
保存当前栈帧状态值,已备后恢复本栈帧时使用(EBP入栈);
将当前栈帧切换到新栈帧(将ESP值装入EBP,更新栈帧底部);
给新栈帧分配空间(把ESP减去所需空间的大小,太高栈顶);
___stdcall调用约定,函数调用指令
;调用前
push 参数3; 假设函数有3个参数,将从右向左依次入栈
push 参数2;
push 参数1;
call 函数地址; call指令将同时完成两项工作:
;a)向栈中压入下一个指令在内存中的位置,即保存返回地址
;b)跳转到所调用函数的入口地址函数入口处
push ebp ; 保存旧栈帧的底部
mov ebp,esp; 设置新栈帧的底部(栈帧切换)
sub esp,xxx; 设置新栈帧的顶部(抬高栈顶,为新栈帧开辟空间)
修改邻接变量
修改邻接变量原理
函数的局部变量在栈中相邻排列。如果局部变量有数组之类的缓冲区,并且程序中存在数组越界缺陷,那么越界的数组就能破坏相邻变量,甚至能破坏EBP、返回地址。
#include<stdio.h>
#define PASSWORD "tel:1234567"
int verify_password(char* password)
{
int authenticated;
char buffer[8];// add local buffto be overflowed
authenticated = strcmp(password,PASSWORD);
strcpy(buffer,password);//over flowd here!
}
int main()
{
int valid_falg = 0;
char password[1024];
while(1)
{
printf("please input password: ");
scanf("%s",password);
valid_flag = verify_password(password);
if(valid_flag)
{
printf("incorrect password\n\n");
}
else
{
printf("Congratulation! you have passed the verification!\n");
break;
}
}
}