我试图理解经典缓冲区溢出漏洞,其中输入缓冲区覆盖堆栈,函数返回地址保存在堆栈和高端内存区域(通常放置shell代码的位置)。 在互联网上有很多这样的例子,我想我已经很好地理解了这一点:
您将更多数据放入开发人员已确定大小的某个输入缓冲区
您的输入会将函数参数和返回地址覆盖到堆栈上的调用函数
现在出现了问题。
到目前为止我读过的所有文章都在寻找DLL中的“JMP ESP”指令的地址(它不能是可重定位的,不能用ASLR编译等)。为什么不在exe中查找“jmp esp”?为什么需要在DLL中?
我在Immunity Debugger中运行了“!mona modules”命令,显示的唯一满足所有这些条件的模块就是exe本身。当我查看流行的漏洞利用数据库时,地址始终在加载的DLL中。
我看不出任何明显的原因。 exe也可以像DLL一样位于内存中的相同地址。有什么不同?
答案 0 :(得分:4)
找到另一个资源: 正如我之前在评论中写的那样,exe的地址通常包含零:
http://resources.infosecinstitute.com/in-depth-seh-exploit-writing-tutorial-using-ollydbg/#commands
您可以考虑使用的模块是主要的可执行文件本身 通常不受任何基于编译器的漏洞利用保护, 特别是当申请由第三方撰写时 开发人员而不是微软。使用主可执行文件有一个主要的 然而,它几乎总是以零字节开始。这个 是一个问题,因为零字节是C / C ++中的字符串终止符, 并使用零字节作为用于溢出缓冲区的字符串的一部分 通常会导致字符串在该点终止 防止缓冲区被适当地溢出和破坏 利用。
答案 1 :(得分:1)
在position independent code中,跳转地址与程序计数器相关,而在非可重定位代码中,它们是绝对的。 Windows中的DLL通常不使用与位置无关的代码。依赖于知道二进制文件中可执行代码的偏移量的漏洞需要不可重定位的代码。
答案 2 :(得分:0)
简短回答:地址不需要在DLL中。
答案很长:
如果指令寄存器设置为其地址,则将执行进程中任何映射的不受保护的可执行存储器。
MAPPED:表示操作系统将内存映射到您的进程,某些地址可能未映射,任何和所有访问都会导致操作系统内存故障信号被提升。
EXECUTABLE:映射内存通常具有设置权限,有时它足以使内存可读,但是具有NX位的新处理器可能需要映射可执行文件
UNPROTECTED:表示内存未映射为保护页面。受保护页保护的存储器页面将引发处理器中断。这些处理取决于您的操作系统,可能用于在不实现NX位的处理器上实现非可执行页面。
如果可执行文件中的内存满足这些要求,则可以将其用于您的漏洞利用。你是否可以在运行时找到这个地址是另一个问题,对于现实世界的漏洞来说可能非常困难。坚持使用不可重定位的DLL和EXE对初学者来说是一个好主意。
至于你的评论:
我再看一下我的例子,我认为答案比我原先想象的容易得多。 exe加载在基地址0x004 ....并上升到0x009 ....这只是意味着每个地址将包含一个0x00,这可能是每个C类程序的显示停止...
尝试使用包含'\0'
个字符的新地址覆盖以前的地址可能会导致使用基于字符串的函数(例如strcpy
或gets
)溢出的漏洞利用溢出缓冲区,因为它们停留在'\0'
个字符上。
如果您可以使用不受'\0'
字符限制的逻辑(例如memcpy
)溢出缓冲区,您也可以使用这些地址。