软件漏洞-缓冲区溢出

概述

漏洞定义:信息系统硬件、软件、OS、网络协议、数据库等在设计上、实现上出现的可以被攻击者利用的错误、缺陷、疏漏(弱点!)

漏洞分类

  • 针对安全操作系统研究提出的漏洞分类方法
  • 将安全漏洞和软件错误结合在一起的漏洞分类方法
  • 多维度分类方法
  • 广义漏洞分类方法
  • 抽象分类方法

漏洞攻击步骤

graph LR
A[漏洞发现]-->B[漏洞分析]-->C[漏洞利用]

漏洞造成后果

  • 以匿名身份直接获取系统最高权限
  • 普通用户提升为管理员用户
  • 实施远程拒绝服务攻击
  • ...

漏洞的标准化研究:CVE(公共漏洞和暴露)、CWE(通用缺陷枚举)

典型漏洞类型

  • 栈溢出
  • 堆溢出
  • 格式化串
  • 整型溢出
  • 释放再使用

栈溢出

原理:程序运行时,计算机会在内存区域开辟一段连续的内存块,包括代码段(.text)、数据段(.data和.bss)和堆栈段(heap、stack)

image-20221025111344726.png

  • 代码段:也称文本段,存放程序的机器码和只读数据;这个段在内存中一般被标记为只读,任何对其的写操作都会导致段错误(segmentation fault)
  • 数据段:包括已初始化的(.data)和未初始化的(.bss),前者存放保存全局的和静态的未初始化变量
  • 堆栈段:

    • 堆:位于BSS内存段的上边,用来存储程序运行时分配的变量;大小不固定,可动态扩张(malloc、new)或缩减(free)
    • 栈:一种用来存储函数调用时的临时信息的结构,如函数调用所传递的参数、函数的返回地址、函数的局部变量等;特性是先进后出,两个基本操作是push和pop

每个进程有一个栈,这个进程中每个函数被调用时分别在栈中占用一段区域,称为栈帧

  • 随着函数调用层数的增加,函数栈帧一块块地向内存低地址方向延伸的
  • 随着函数调用层数的减少,即各函数调用的返回,栈帧会一块块地被遗弃而向内存的高地址方向回缩
  • 各函数的栈帧大小由函数地局部变量数目决定
  • 溢出中主要关注数据区和堆栈区

使用时两个最重要的寄存器:SP(ESP,栈顶指针)和BP(EBP,基地址/栈底指针)

函数被调用时栈地压入情况:

image-20221025151154358.png

  1. 传递给Func的实参从右到左依次入栈
  2. call指令调用Func函数,并把call指令的下一条指令的地址(EIP中的值)作为返回地址压入栈中,之后跳转到被调用函数入口处
  3. 保存调用函数的栈底地址(push ebp),进行栈帧切换,把栈指针ESP拷贝到EBP,作为新的基地址(mov ebp, esp)
  4. 从ebp处开始存放被调用函数中的局部变量和临时变量,抬高栈顶(sub esp, xxx),变量的地址依次减小,先定义的变量先入栈;

函数调用返回时降低栈顶(add esp, xxx),恢复栈帧(pop ebp),被调函数执行完毕(ret,返会地址弹给EIP)

局部变量下面是前一个调用函数的EBP和返回地址,如果局部变量发生溢出,很可能覆盖掉EBP甚至RET,即缓冲区溢出攻击的原理

溢出漏洞的原理

溢出攻击的基本流程

graph TB
A[注入恶意数据]-->B[溢出缓冲区]-->c[控制流重定向]-->D[执行有效荷载]

溢出利用的关键技术

  • 溢出点定位:探测法、反汇编分析
  • 覆盖执行控制地址:执行控制地址包括返回指针、函数指针变量、异常处理结构等
  • 覆盖异常处理结构:程序异常时系统中断当前线程,将控制权交给异常处理程序;Windows异常处理机制称为结构化异常处理(Structured Exception Handling)
  • 跳转地址的确定:

    • 跳转指令的选取:jmp esp、call ebx、call ecx等
    • 跳转指令的搜寻范围:用户空间的任意地址、系统dll、进程代码段、PEB、TEB
  • shellcode定位和跳转

image-20221025170625706.png

最后修改:2022 年 11 月 13 日
如果觉得我的文章对你有用,请随意赞赏