看一些基于堆栈的基本缓冲区溢出,我对调用者的ebp在basic return address overwrite与off-by-one ebp overwrite中的差异感到困惑。
在返回地址覆盖中,目标是粉碎堆栈足以覆盖返回地址,从而控制eip。
在一次攻击中,呼叫者的ebp的LSB被覆盖。这会强制ebp弹出,esp会移动到攻击者控制的缓冲区内,这会引起对返回地址的控制,从而导致eip。
我的困惑源于ebp的行为。在基本的返回地址覆盖中,我们用垃圾字节覆盖调用者的ebp显然并不重要,但ebp的值需要在一次攻击中保持一致。函数结尾如何在基本缓冲区溢出情况下工作?
innerFunction
答案 0 :(得分:1)
在基本的返回地址覆盖中,正如您所说,您可以直接覆盖ret
,因此只有retn
在函数结尾的指示中很重要。
在一个off-by-one ebp覆盖中显然你知道你不能覆盖ret
,但是你可以将堆栈转移到用户控制的地方。
在这种情况下,攻击者至少要通过两个功能结局来获得控制权。
逐个ebp覆盖
mov esp, ebp
pop ebp ; now ebp is partially overwriten
retn
将筹码转移到受控区域。
mov esp, ebp ; now stack(esp) is moved to controlled area.
pop ebp ; controlled
retn ; controlled --> gain eip control