我试图了解经典的缓冲区溢出漏洞,其中输入缓冲区会覆盖堆栈,函数返回地址将保存在堆栈和上层内存区域(通常将shell代码放在此处)中。
互联网上有很多这样的例子,我想我已经很好地理解了这一点:

  • 您将更多数据放入开发人员已将其固定大小的某些输入缓冲区中
  • 您的输入将覆盖函数参数和堆栈上调用函数的返回地址
  • 当操作系统试图从发生溢出的功能中返回时,该地址已加载到EIP中,这就是使您可以将您控制的数据获取到EIP寄存器中的原因(当不仔细阅读某些文章时,您会感觉可以覆盖CPU寄存器,当然不是这样,您只能覆盖堆栈,但CPU会将堆栈中的地址加载到其寄存器中)
  • 如果漏洞利用程序设计合理,则加载到EIP中的值将使程序跳至Shell代码的开头(请参见第5点)。
  • 我想我很了解的下一件事是“JMP ESP”机制。在实验室环境中复制崩溃时,您会在内存中寻找一个包含“JMP ESP”指令的位置,然后用该地址覆盖EIP(现在我的措词不准确,我知道...)。至少对于相同的OS版本,无论您多久运行一次,何时运行,哪个线程在执行您的任务等,该地址都必须相同。代码将跳转到该地址(同时堆栈减少4个字节),因此“jmp esp”将跳转到溢出缓冲区中下一个我将其值用来覆盖EIP的位置之后的地址。通常是shellcode所在的地方,可能以NOP开头。

  • 现在出现了问题。

    到目前为止,我已阅读的所有文章都在DLL中寻找“JMP ESP”指令的地址(该地址不能重定位,不能用ASLR编译,等等)。为什么不在exe本身中寻找“jmp esp”呢?为什么它需要在DLL中?
    我已经在Immunity Debugger中运行了“!mona modules”命令,并且显示的满足所有这些条件的唯一模块是exe本身。当我查看流行的漏洞利用数据库时,该地址始终位于已加载的DLL中。

    我看不出有任何明显的原因。该exe也可以以与DLL相同的方式位于内存中的同一地址。有什么区别?

    最佳答案

    在此找到了另一个资源:
    正如我之前在评论中所写,exe的地址通常包含零:

    http://resources.infosecinstitute.com/in-depth-seh-exploit-writing-tutorial-using-ollydbg/#commands

    关于c - 缓冲区溢出漏洞: Why does "jmp esp" need to be located in a DLL?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34369379/

    10-13 09:31