在缓冲区溢出/程序集 MOV 中覆盖堆栈异常处理程序 (SEH)
Overwriting stack exception handler (SEH) in buffer overflow / Assembly MOV
我正在尝试通过覆盖位于此处的堆栈异常处理程序 (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 link 到同一页:https://repo.zenk-security.com/Reversing%20.%20cracking/%20Bypassing%20Stack%20Cookies,%20SafeSeh,%20HW%20DEP%20and%20ASLR.pdf
我有疑问的部分在Stack cookie bypass demonstration 2 : Virtual Function call 网站或 PDF 第 30 页
寄存器的初始状态:
post 然后说:
...these 4 instructions are executed, attempting to load the
address of the function into 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]
The end result of these 4 instructions is
然后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) 值后列出的 post 不匹配。
我的解读出了什么问题? EDX == ECX 不应该吗?谢谢。
对,好像有误
理论
所描述的方法通过在函数 returns 之前转移执行流程来绕过 GS 保护(并检查金丝雀)。
这是通过缓冲区溢出对在堆栈中进一步分配的 C++ 对象的 vtable
进行污染来实现的。
具有虚拟成员的 C++ 对象的布局增加了指向 vtable
的隐藏指针。
这个指针是 class 在内存中布局的第一个成员,参见 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.vtable
。 edx = 40211ch
(指向此 C++ 对象的 vtable)。
对于 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
.
我正在尝试通过覆盖位于此处的堆栈异常处理程序 (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 link 到同一页:https://repo.zenk-security.com/Reversing%20.%20cracking/%20Bypassing%20Stack%20Cookies,%20SafeSeh,%20HW%20DEP%20and%20ASLR.pdf
我有疑问的部分在Stack cookie bypass demonstration 2 : Virtual Function call 网站或 PDF 第 30 页
寄存器的初始状态:
post 然后说:
...these 4 instructions are executed, attempting to load the address of the function into 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]
The end result of these 4 instructions is
然后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) 值后列出的 post 不匹配。
我的解读出了什么问题? EDX == ECX 不应该吗?谢谢。
对,好像有误
理论
所描述的方法通过在函数 returns 之前转移执行流程来绕过 GS 保护(并检查金丝雀)。
这是通过缓冲区溢出对在堆栈中进一步分配的 C++ 对象的 vtable
进行污染来实现的。
具有虚拟成员的 C++ 对象的布局增加了指向 vtable
的隐藏指针。
这个指针是 class 在内存中布局的第一个成员,参见 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.vtable
。 edx = 40211ch
(指向此 C++ 对象的 vtable)。
对于 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
.