如何使用缓冲区溢出攻击替换堆栈上的返回地址

Kev*_*ica 4 x86 assembly buffer-overflow

对于家庭作业,我正在执行一系列缓冲区溢出攻击.我得到了一个程序来反汇编,C中gets()的源代码用于不正确调用的函数,以及我应该强制程序调用的其他几个函数的源代码.对于其中一项任务,我必须:

  • 然后,注入一些更改值的代码
  • 返回上述方法之一

在确定返回的位置时,我不明白程序在堆栈中的位置.存储在堆栈中的方法的返回地址在哪里?

该程序是为x86编译的.

nin*_*alj 13

你需要知道的:

  • EIP是一个指向下一条执行指令的寄存器.
  • 在调用函数时,参数然后EIP(因此被调用的函数知道返回的位置)被保存在堆栈中.

  • 当编译器被告知(显式或隐式)使用帧指针时,它会将帧指针(在EBP寄存器中)保存在堆栈上(因此它可以稍后将帧指针恢复为它在调用函数上的值) ,然后将帧指针设置为指向堆栈的当前顶部.这允许从已知的引用点(帧指针)轻松访问参数和局部变量,并大大简化了调试.

  • 然后,为局部变量保留空间,并执行该函数.
  • 从函数返回时,恢复前一帧指针和指令指针.

x86上的函数调用类似于:

                                        ...
int main()                              add  $-0x8,%esp ; alignment
{                                       push $0x2       ; arg 2
        ...                             push $0x1       ; arg 1
        func(1, 2);                     call func       ; function call
        ...                             add  $0x10,%esp ; pop args from stack
}                                       ...
Run Code Online (Sandbox Code Playgroud)

被调用的函数看起来像:

void func(int arg1, int arg2)           push %ebp       ;\
{                                       mov  %esp,%ebp  ;/ create stack frame
        int local1;                     sub  $0x18,%esp ; reserves space
        ...                             ...
}                                       mov  %ebp,%esp  ;\
                                        pop  %ebp       ;/ destroys frame
                                        ret             ; returns
Run Code Online (Sandbox Code Playgroud)

因此,堆栈看起来类似于:

          :           :
          +-----------+
          : alignment :
          +-----------+
12(%ebp)  |   arg2    |
          +-----------+
 8(%ebp)  |   arg1    |
          +-----------+
 4(%ebp)  |    ret    | -----> return address
          +-----------+
  (%ebp)  |    ebp    | -----> previous ebp
          +-----------+
-4(%ebp)  |  local1   | -----> local vars
          +-----------+
          : alignment :
          +-----------+
          :           :
Run Code Online (Sandbox Code Playgroud)

(ASCII地址较低的地址较低)