C 缓冲区溢出漏洞:为什么;jmp esp";需要位于DLL中吗?
我试图理解经典的缓冲区溢出漏洞,即输入缓冲区覆盖堆栈、保存在堆栈上的函数返回地址和上层内存区域(通常放置shell代码的位置)。 互联网上有很多这样的例子,我想我已经非常清楚了:C 缓冲区溢出漏洞:为什么;jmp esp";需要位于DLL中吗?,c,dll,buffer-overflow,C,Dll,Buffer Overflow,我试图理解经典的缓冲区溢出漏洞,即输入缓冲区覆盖堆栈、保存在堆栈上的函数返回地址和上层内存区域(通常放置shell代码的位置)。 互联网上有很多这样的例子,我想我已经非常清楚了: 您将更多的数据放入开发人员已确定大小的输入缓冲区中 您的输入将覆盖堆栈上调用函数的函数参数和返回地址 当操作系统试图从发生溢出的函数返回时,该地址被加载到EIP中,这就是允许您将控制的数据获取到EIP寄存器中的原因(如果不仔细阅读某些文章,您会觉得您可以覆盖CPU寄存器。当然,情况并非如此,您只能覆盖堆栈,但CPU会将
我看不出有什么明显的原因。exe也可以像DLL一样位于内存中的同一地址。有什么区别吗?在跳转地址中是相对于程序计数器的,而在不可重定位的代码中是绝对的。Windows中的DLL通常不使用位置无关的代码。依赖于kn的攻击由于二进制文件中可执行代码的偏移量,因此需要不可重定位的代码。在此上找到另一个资源: 正如我之前在评论中所写,exe的地址通常包含零:
一个你可以考虑使用的模块,它是主要的可执行文件本身, 通常不受任何基于编译器的漏洞利用保护, 尤其是当应用程序由第三方编写时 开发人员,而不是Microsoft。使用主可执行文件有一个主要 然而,它的缺陷在于它几乎总是以零字节开始 是一个问题,因为零字节是C/C++中的字符串终止符, 使用零字节作为用于溢出缓冲区的字符串的一部分将 通常会导致字符串在该点终止,可能 防止缓冲区适当溢出和中断 剥削
简短回答:地址不需要在DLL中 长答覆: 如果指令寄存器设置为其地址,则将执行进程中任何映射的无保护可执行内存 MAPPED(已映射):表示内存由操作系统映射到进程,某些地址可能未映射,任何和所有访问都会导致引发操作系统内存故障信号 可执行文件:映射内存通常具有设置为它的权限,有时它足以使内存可读,但对于具有NX位的较新处理器,它可能需要映射为可执行文件 未受保护:表示内存未映射为保护页。受保护页保护的内存页将引发处理器中断。对这些页的处理取决于您的操作系统,并可用于在未实现NX位的处理器上实现不可执行页 如果可执行文件中的内存满足这些要求,则可将其用于攻击。运行时是否能找到此地址是另一个问题,对于真实世界的攻击可能非常困难。对于初学者来说,坚持使用不可重定位的DLL和EXE是一个好主意 关于你的评论:
我再看一次我的例子,我认为答案比我原来想象的简单得多。exe加载在基址0x004…并上升到0x009…这意味着每个地址将包含一个0x00,这可能是每个C类程序的显示停止符 尝试使用包含
'\0'
字符的新地址溢出以前的地址,可能会导致在基于字符串的函数(例如strcpy
或gets
)中使用溢出漏洞来溢出缓冲区,因为这些漏洞在'\0'
字符上停止
如果您可以使用不受
'\0'
字符限制的逻辑溢出缓冲区(例如memcpy
)您也可以使用这些地址。仔细想想。哪种攻击最有可能成功?一个与您希望的版本完全相同的EXE或一个在许多进程中使用的DLL已经存在了一段时间,并且EXE所有者不容易更改它?好的,那么基本上您在说什么