assembly - 在缓冲区溢出/程序集 MOV 中覆盖堆栈异常处理程序 (SEH)
问题描述
我试图通过覆盖位于此处的堆栈异常处理程序 (SEH) 来解释绕过堆栈 cookie:https ://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-第 6 部分绕过堆栈cookies-safeseh-hw-dep-and-aslr/
我有疑问的部分在Stack cookie bypass demo 2 : Virtual Function call of the website or page 30 of the PDF
寄存器的初始状态:
然后帖子说:
...执行这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 吗?谢谢。
解决方案
是的,似乎有错误
理论
所描述的方法通过在函数返回(并检查金丝雀)之前转移执行流程来绕过 GS 保护。
这是通过通过vtable
缓冲区溢出的方式在堆栈中进一步分配的 C++ 对象的污染来实现的。
具有虚拟成员的 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)
. 我们持有指向ie的 指针
。(指向此 C++ 对象的 vtable 的指针)。我们持有指向ie的指针。.MOV EDX,DWORD PTR DS:[EAX]
edx
this[0]
this.vtable
edx = 40211ch
MOV EAX,DWORD PTR DS:[EDX]
eax
this.vtable[0]
&bar
eax = 401070h (ptr to bar)
MOV ECX,DWORD PTR SS:[EBP-10]
只是移动this
到,这ecx
是thiscall
(没有双关语)调用约定。
这也是为什么我认识到那[ebp-10h]
是this
而不是指向另一个对象的指针。
执行
复制后的堆栈是(正如您发布的那样):
我们可以看到C++对象没有被触及,复制的缓冲区太短了。
攻击者还需要一个 DWORD,在缓冲区中包含一个指针,他们在其中制作了一个新的vtable
.
推荐阅读
- spring - 如何在 Mono webflux 中返回 HttpStatus 204
- unity3d - 一次只有一个对象的实例
- android - 如何通过连接在我的 toast 中显示模型类中的 tvItem?
- angular - 在 ag-grid 中切换到自定义单元格渲染器
- arrays - 如何在小于 O(n) 的时间内找到至少出现 k 次的有序数组中的元素?
- postgresql - 当我想查看 PostgreSQL 是否正在工作时,我收到一个错误代码
- c# - 如何选择最后一个插入ID而不发生冲突
- sql - SQL 1/count 返回无行
- sql - 有没有更好的方法将多个列值从表连接到另一个?
- sharepoint - 按“当前用户组成员”筛选 SharePoint 列表