堆栈溢出攻击是黑客攻击中最常用的攻击手段,臭名昭著的Morris worm是世界上第一个用到堆栈溢出攻击的病毒,据统计在1988年破坏了6000台主机。而在8年之后的1996年,Alpha One 通过发表在Phrack杂志上的论文“Smashing The Stack For Fun And Profit”让堆栈溢出攻击的原理公开,从此这一攻击手法变成了黑客“入门级别”。
因为课程安排要求读这个paper,所以逐段做解读:
一.简介:
在这一部分中讲到了写这篇论文的原因,论文要阐明的事情即什么是缓冲区溢出以及缓冲区溢出攻击是怎么工作的?论文中实验环境是x86和linux系统。
二.进程在内存中的组织方式:
这一部分是讲进程在内存中的组织形式。进程在内存中区分成三个区域:代码段(Text)、数据段(Data)和堆栈(Stack)。由上图可以看到在内存中的分布是由低地址到高地址。实际上这里他只是做了一个简单的介绍,程序在内存中的分配要复杂的多,下面的图略详细一些(出自《UNIX环境高级编程》):
各段中存放的内容如下:
- 代码段:全局常量(const)、字符串常量、函数以及编译时可决定的某些东西
- 数据段(初始化):初始化的全局变量、初始化的静态变量(全局的和局部的)
- 数据段(未初始化)(BSS):未初始化的全局变量、未初始化的静态变量(全局的和局部的)
- 堆:动态分配的区域(malloc、new等)
- 栈:用户程序的函数栈帧(包括参数、初始化以及未初始化的局部变量,但不包含静态变量、局部常量(const)),用于调度函数的调用执行
- 命令行参数和环境变量顾名思义存放命令行参数和环境变量
注意:1.对于代码段只有读和执行的权限,对于数据段只有读写的权限。当对他们做了非法的操作时便会出现段错误。
2.对于代码段和数据段在程序编译时就已经分配好,而堆和栈是在程序运行时才进行分配的。
2.1 what is a stack & why do we use a stack
这一部分是讲栈的性质也就是先进后出。但是我们为什么要用到栈,因为现代计算机的设计都是需要高级语言的,而高级语言的主要技术特性就是过程和函数。在程序运行时会调用函数,这就像jump指令一样,但是不同于jump的是,被调用的函数执行完之后,还要返回到之前的语句继续执行,这就用到了栈的先进先出的性质。
2.2 The Stack Region
栈是包含数据的连续的内存块,寄存器SP指向栈顶,栈底是固定的地址。他的大小在程序运行时自动变化。cpu执行push和pop指令。栈由逻辑堆栈帧组成,当调用函数时他会被push,返回时会被pop。一个堆栈帧由以下几部分组成:
1).函数的返回地址和参数
2)临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
3)保存的上下文:包括在函数调用前后需要保持不变的寄存器
对于这一部分的内容在《程序员的自我修养》一书