在缓冲区溢出/程序集MOV中覆盖堆栈异常处理程序(SEH)

时间:2018-08-17 18:05:08

标签: assembly stack-overflow cpu-registers virtual-functions seh

我正在尝试通过覆盖位于以下位置的堆栈异常处理程序(SEH)来绕过堆栈cookie的解释:https://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/

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

我有一个疑问的部分位于网站的堆栈cookie旁路演示2:虚拟函数调用下或PDF的第30页

寄存器的初始状态:

pic1 initial

帖子然后说:

  

...这4条指令已执行,试图加载   函数的地址转换为eax ...

 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条指令的最终结果是

after

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

我的问题:

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

我的理解是第一条说明

之后的内容
 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不应该吗?谢谢。

1 个答案:

答案 0 :(得分:3)

是的,看来有误

理论

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

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

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

使用MOV EAX,DWORD PTR SS:[EBP-10]时,eax持有指向C ++对象的指针,即this,因为我们位于成员函数和[ebp-10h] = original ecx中(见下文)。 eax = 12FF78h (ptr to this C++ object)
使用MOV EDX,DWORD PTR DS:[EAX],我们有edx持有指向this[0]的指针,即this.vtableedx = 40211ch(此C ++对象的vtable的ptr)。 使用MOV EAX,DWORD PTR DS:[EDX],我们有eax持有指向this.vtable[0]的指针,即&bareax = 401070h (ptr to bar)

MOV ECX,DWORD PTR SS:[EBP-10]仅将this移到ecx中,这就是thiscall(无双关语)的调用约定。
这也是为什么我认识到[ebp-10h]this而不是指向另一个对象的指针的原因。

实施

复制后的堆栈(与您发布的完全相同):

The stack after the copy, the vtable is not corrupted

我们可以看到尚未触摸C ++对象,复制的缓冲区太短。
攻击者将需要一个DWORD,在缓冲区中包含一个指针,在那里他们可以制作新的vtable