如何使用缓冲区溢出攻击替换堆栈上的返回地址(How to replace the return ad

2019-08-02 04:29发布

对于一个家庭作业,我进行了一系列的缓冲区溢出攻击。 我得到了一个程序来拆卸,在C源代码是不正确调用一个函数gets() ,并为我应该强制程序调用其他几个功能的源代码。 对于任务之一,我必须:

  • 注入一些代码,变化的值,然后
  • 回到前述的方法之一

我不明白的地方确定在哪里返回时,程序会在堆栈中的主要的事情。 在哪里保存在栈上的返回地址的方法?

该程序被编译为86。

Answer 1:

你需要知道的:

  • 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
}                                       ...

而调用的函数看起来是这样的:

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

因此,堆栈将类似于:

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

(下地址是下对ASCII艺术)



文章来源: How to replace the return address on the stack using a buffer overflow attack