缓冲区溢出
漏洞标准化研究
- 公共漏洞和暴露CVE
字典表,为广泛认同/已经暴露的漏洞给出公共名称以及相应修补信息。 - 通用缺陷枚举CME
包括类缺陷、基础缺陷和变种缺陷,有字典、开发和研究三种视图。字典把所有缺陷按字母表顺序排列以供查阅;开发以软件开发周期为参照进行分类;研究从内在性质等方面进行分类。
典型漏洞类型
栈溢出
- 栈和栈帧
程序运行时在内存中会有一块连续区域,从内存地址高到低一次是栈、堆、数据段、代码段。
1)栈:由编译器自动分配释放,存放临时创建的局部变量和参数等。先进后出,便于保存/恢复函数调用现场。每个进程对应一个栈空间,进程中每个函数独占一个栈帧。
2)堆:位于BSS内存段上面,由程序员分配释放,程序结束时操作系统统一回收。大小不固定,可以动态扩张和缩减。
3)数据段:包括已初始化的数据段(.data)和未初始化的数据段(.bss),在编译时分配。
4)代码段:存放由处理器直接执行的二进制代码和只读数据,可执行指令就是从这里取得的。一般标记为只读,任何对该区的写错误都会产生段错误。 - 程序和栈
1)随着函数调用层数增加,函数栈帧向低地址方向延伸。随着各层调用函数返回,栈帧一块块被遗弃,向高地址方向回缩。
2)两个相关寄存器:SP是栈顶指针,随数据出入栈变化。BP是栈底指针,标识一个相对稳定位置,BP加偏移地址可以引用参数和局部变量。
3)每个栈帧包含4个部分:前栈帧ebp、临时局部变量、函数参数、返回地址。 - 函数调用机制
1)调用函数把被调用函数的参数按照与形参顺序相反的顺序压入栈中。
2)使用call指令调用被调函数。call完成压入返回地址(返回地址是call的下一条指令的地址)和调转到被调用函数的入口。
3)转入被调用函数,先压入调用者函数的ebp,然后进行栈帧切换(把调用者函数的栈顶切换成被调用函数的栈底)。
4)此时esp和ebp指向相同位置,然后开始压入被调函数的局部变量和临时变量,各个变量按照定义的顺序入栈。 - 函数调用返回机制
1)降低栈顶,收回当前函数分配的存储局部变量和临时变量的存储空间。
2)恢复保存的前栈帧栈底地址。
3)被调用函数执行完毕,执行retn指令,返回调用者函数继续执行。 - 栈溢出
由于栈从高到低依次是函数变量、前栈帧ebp和前栈帧中的返回地址,所以如果变量大小超过了给变量分配的存储空间,就会覆盖位于低地址的前栈帧ebp和前栈帧中的返回地址。所以如果精心设置用于覆盖返回地址的值,就可以通过给变量赋值来控制程序跳转到其他代码空间执行,即利用栈溢出实现控制流劫持。
环境变量
环境变量的内存位置
envp和environ最初指向同一个位置。envp只能在主函数中访问,environ是一个二级指针全局变量。更改环境变量时,其存储位置可能被移到堆中,此时environ的值改变,envp的值不变。
shell命令变量和环境变量
二者是不同的。shell启动时会将环境变量复制到自己的shell中,但修改shell变量不会影响环境变量。
/proc是linux的虚拟文件系统,用进程ID作为目录名称,每个目录都有一个名为environ的虚拟文件,其中包含该进程的环境变量。在bash shell中调用env时会在子进程中运行,所以打印的是shell子进程的环境变量,而不是自身的环境变量。