Swing'Blog 浮生若梦 Swing'Blog 浮生若梦
  • Home
  • |
  • About
  • |
  • Articles
  • |
  • RSS
  • |
  • Categories
  • |
  • Links

基础栈溢出复习 之基础

2017-03-18 Updated on 2020-02-17 Summary

Table of Contents

  1. 函数调用
  2. 函数调用指令: call ret
  3. 函数约定:
  4. 参数传参:取决于调用约定,一般情况下:
  5. 寄存器
  • 堆栈溢出原理
  • 栈溢出的保护机制
    1. 栈上的数据无法被当作指令来执行
    2. 难以找到想要找的地址
    3. 检测栈数据是否被修改
      1. CTF 常用套路: 栈溢出的利用方法
  • 现代栈溢出利用技术基础:ROP
  • 栈与系统栈

    栈:一种先进先出的数据结构。常见操作有两种,进栈(PUSH) 和弹栈(POP),用于标识栈的属性有两个,一个是栈顶(TOP),一个是栈底(BASE
    程序中的栈:

    • 内存中的一块区域,用栈的结构来管理,从高地址向低地址增长
    • 寄存器esp代表栈顶(即最低栈地址)
    • 栈操作
      • 压栈(入栈)push sth-> [esp]=sth,esp=esp-4
      • 弹栈(出栈)pop sth-> sth=[esp],esp=esp+4
    • 栈用于保存函数调用信息和局部变量
      函数调用
      如何通过系统栈进行函数的调用和递归
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      int fun_b(x,y){
      int var_b1,var_b2;

      rutrun var_b1 * var_b2 ;
      }
      int fun_a(a,b){
      int var_a;
      var_a = fun_b(a*b)

      }
      int main(int argc,chr **argv,chr **envp)
      {
      int var_main;
      var_main = func_a{5,5};
      rutrun var_main;

      }
      函数的分布应当是:

      当CPU调用func_A函数,会从main函数对应的机器指令跳转到func_A,取值在执行,执行结束后,需要返回又会进行跳转…….以此类似的跳转过程。
    函数调用指令: call ret

    大致过程:

    • 参数入栈
    • 返回地址入栈
    • 代码区块跳转
    • 栈帧调整:
      保存当前栈帧的状态值,为了后面恢复本栈帧时使用(EBP入栈);
      将当前的栈帧切换到新栈帧(ESP值装入EBP,更新栈帧底部)
      给新栈帧分配空间(ESP减去所需要空间的大小,抬高栈顶)
      相关指令:
    • Call func -> push pc, jmp func
    • Leave ->mov esp,ebp, pop ebp
    • Ret -> pop pc
    函数约定:
    • __stdcall,__cdecl,__fastcall,__thiscall,__nakedcall,__pascal
      以 __fastcall为例子:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      push  参数 3               #参数由右向左入栈
      push 参数 2
      push 参数 1
      call 函数地址 #push当前指令位置,跳转到所调用函数的入口地址

      push ebp #保存旧栈帧的底部
      mov ebp,esp #设置新栈帧底部
      sub esp ,xxx #设置新栈帧顶部

      参数传参:取决于调用约定,一般情况下:
    • X86 从右向左入栈,X64 优先寄存器,参数过多时才入栈
    寄存器

    重要的寄存器:rsp/esp, pc, rbp/ebp, rax/eax, rdi, rsi, rdx, rcx
    ESP: 栈指针寄存器,内存存放着一个指针,指针指向系统栈最上面一个栈帧的底部
    EBP:基址指针寄存器,存放着一个指针,指针指向系统栈最上面的一个栈帧底部

    堆栈溢出原理

    通俗的讲,栈溢出的原理就是不顾堆栈中分配的局部数据块大小,向该数据快写入了过多的数据,导致数据越界,结果覆盖来看老的堆栈数据。

    栈溢出的保护机制

    栈上的数据无法被当作指令来执行
    • 数据执行保护(NX/DEP)
    • 绕过方法ROP
      难以找到想要找的地址
    • 地址空间布局随机化(ASLR)
    • 绕过方法:infoleak 、retdlresolve 、ROP
      检测栈数据是否被修改
    • Stack Canary/ Cookie
    • 绕过方法: infoleak
    • 如今 计算机保护 基本上都是NX+Stack Canary +ASLR
      CTF 常用套路: 栈溢出的利用方法
    • 现代栈溢出利用技术基础:ROP
    • 利用signal机制的ROP技术:SROP
    • 没有binary怎么办:BROP 、dump bin
    • 劫持栈指针:stack pivot
    • 利用动态链接绕过ASLR:ret2dl resolve、fake linkmap
    • 利用地址低12bit绕过ASLR:Partial Overwrite
    • 绕过stack canary:改写指针与局部变量、leak canary、overwrite canary
    • 溢出位数不够怎么办:覆盖ebp,Partial Overwrite

      现代栈溢出利用技术基础:ROP

      讲道理学习ROP ,看蒸米的文章是最实在的。蒸米的一步一步学ROP简直是经典篇目。

    ROP的基础学习可以看我翻译的一篇文章

    分类: Summary
    标签: pwn
    ← Prev 基础栈溢出复习 二 之 ROP
    Next → 2017 XCTF 南京站 线上赛 NJCTF

    Comments

    © 2015 - 2026 Swing
    Powered by Hexo Hexo Theme Bloom