数组越界访问
1 数组越界
先区分一下数组越界漏洞和溢出漏洞:
- 数组越界访问包含读写类型
- 溢出属于数据写入
- 部分溢出漏洞本质确实就是数组越界漏洞。
数组越界就像是倒水的时候倒错了杯子,溢出就像是水从杯子里溢出来。
1.1 原理
堆中的数组越界: 因为堆是我们自己分配的,如果越界会把堆中其他空间的数据写掉或着读取其他空间的数据。如果是变量则会引起数值改变,如果是指针则可能会引起crash。
栈中的数组越界:因为栈是向下增长的,进入函数前,会把参数和下一条指令地址压栈,如果覆盖了当前函数的ebp(栈底),那么栈还原时esp(栈顶)就不正确指向,从而发送未知错误(大部分是程序崩溃退出),ebp后面的返回地址也被覆盖那么程序执行流程则可被控制。
下面代码为例分析数组越界访问漏洞:
#include<stdio.h>
int main(){
int index;
int array[3] = {111,222,333};
printf("输入数组索引下标:");
scanf("%d",&index);
printf("输出数组元素:array[%d] = %d\n", index, array[index]);
//array[index] = 1;
return 0;
}
执行生成的程序,然后分别输入2 和 4 作为数组下标,输出结果如下,当输入的数组下标为 0、1、2 的时候,会得到正常数值,但是从索引3开始就超出了原来的数组 array 的范围,比如输入4,将会数组越界访问栈中的值,导致读取不在程序控制范围内的数值。
使用gdb调试发现array[4] 就是从 array 开始的第六个数据0x4012A9,已经读取到了array之外的数据,如果越界访问距离过大,就会访问到不可访问的内存空间,导致程序崩溃。
我们可以利用这种方式来取得栈上的 canary,进而绕过canary。
canary = 0x3dd8e70f8 =1037625103~10~
这里我们已经取得了栈中 canary 的值,接下来只要通过栈溢出,进行覆盖,并把 canary 放入 [rbp-0x8] 就能控制程序去执行 shellcode 了。
0x9d5720fbb2e21300
参数:
漏洞战争