首页 > 解决方案 > 在缓冲区溢出/程序集 MOV 中覆盖堆栈异常处理程序 (SEH)

问题描述

我试图通过覆盖位于此处的堆栈异常处理程序 (SEH) 来解释绕过堆栈 cookie:https ://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-第 6 部分绕过堆栈cookies-safeseh-hw-dep-and-aslr/

PDF链接到同一页面:https ://repo.zenk-security.com/Reversing%20.%20cracking/%20Bypassing%20Stack%20Cookies,%20SafeSeh,%20HW%20DEP%20and%20ASLR.pdf

我有疑问的部分在Stack cookie bypass demo 2 : Virtual Function call of the website or page 30 of the PDF

寄存器的初始状态:

图1 最初的

然后帖子说:

...执行这4条指令,试图将函数的地址加载到eax中...</p>

 0040104D  |. 8B45 F0        MOV EAX,DWORD PTR SS:[EBP-10]
 00401050  |. 8B10           MOV EDX,DWORD PTR DS:[EAX]
 00401052  |. 8B4D F0        MOV ECX,DWORD PTR SS:[EBP-10]
 00401055  |. 8B02           MOV EAX,DWORD PTR DS:[EDX]

这 4 条指令的最终结果是

后

然后CALL EAX将被调用,执行 EAX 中修改后的函数指针地址。

我的问题:

在提到的 4 条指令之后,EAX 和 EDX 如何指向被覆盖的字符串?

我的理解是在第一条指令之后,

 MOV EAX,DWORD PTR SS:[EBP-10]

EBP (0012FF6C) 减 10(十六进制?)等于 0012FF5C。位置 0012FF5C 的值为 0012FF78。0012FF78 是作为参数传递的堆栈中进一步向上的 SEH 的位置。所以 EAX = 0012FF78。到目前为止一切顺利,因为 0012FF78 是指向 SEH 的指针的地址,位于堆栈的更上方。

第二条指令,

 MOV EDX,DWORD PTR DS:[EAX]

EDX 设置为 EAX 指向的位置的值。位置 0012FF78 的值为 0040211C。EDX = 0040211C?

第三条指令,

 MOV ECX,DWORD PTR SS:[EBP-10]

ECX 设置为 0012FF78,这与第一条指令相同,但使用 ECX 而不是 EAX。该指令对这种情况重要吗?

第四条指令,

 MOV EAX,DWORD PTR DS:[EDX]

EAX 设置为 EDX (0040211C) 引用的值。EAX = ??? 内存中那个位置的任何东西。

我计算的 EAX (???) 和 EDX (0040211C) 与 EAX (42424242) 和 EDX (0012FF78) 的值之后列出的帖子不匹配。

我的解释出了什么问题?EDX 不应该 == ECX 吗?谢谢。

标签: assemblystack-overflowcpu-registersvirtual-functionsseh

解决方案


是的,似乎有错误

理论

所描述的方法通过在函数返回(并检查金丝雀)之前转移执行流程来绕过 GS 保护。
这是通过通过vtable缓冲区溢出的方式在堆栈中进一步分配的 C++ 对象的污染来实现的。

具有虚拟成员的 C++ 对象的布局增加了指向vtable.
该指针是在内存中布局的类的第一个成员,请参见this

该对象分配在堆栈上的某个位置,但指向它的指针存储在[ebp-10h](有效地址 0x12FF5C),您可以通过查看 10 00401010 894df0 mov dword ptr [ebp-10h],ecxPDF 的第 27 页上的指令(更多内容见下文)来了解这一点,其中受害者函数的反汇编是显示。

MOV EAX,DWORD PTR SS:[EBP-10]我们eax持有指向 C++ 对象的指针,即因为this我们在一个成员函数中并且[ebp-10h] = original ecx(见下文)。eax = 12FF78h (ptr to this C++ object). 我们持有指向ie的 指针
。(指向此 C++ 对象的 vtable 的指针)。我们持有指向ie的指针。.MOV EDX,DWORD PTR DS:[EAX]edxthis[0]this.vtableedx = 40211chMOV EAX,DWORD PTR DS:[EDX]eaxthis.vtable[0]&bareax = 401070h (ptr to bar)

MOV ECX,DWORD PTR SS:[EBP-10]只是移动this到,这ecxthiscall(没有双关语)调用约定。
这也是为什么我认识到那[ebp-10h]this而不是指向另一个对象的指针。

执行

复制后的堆栈是(正如您发布的那样):

复制后的栈,vtable没有损坏

我们可以看到C++对象没有被触及,复制的缓冲区太短了。
攻击者还需要一个 DWORD,在缓冲区中包含一个指针,他们在其中制作了一个新的vtable.


推荐阅读