articles icon indicating copy to clipboard operation
articles copied to clipboard

SEH执行shellcode的原理

Open xinali opened this issue 6 years ago • 0 comments

SEH执行shellcode的原理

windbg推导栈溢出导致SEH代码执行

测试代码vc6.0编译,win2000测试

#include "stdafx.h"
#include <string.h>
#include <windows.h>

char shellcode[] = 
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61";

DWORD MyException(void)
{
	printf("There is an exception");
	return 1;
}
void test(char * input)
{
	char str[200];
		
    int zero=0;
	__try
	{
		strcpy(str,input);
	    zero=1/zero;
	}
	__except(MyException())
	{
	}
}
int main()
{
	test(shellcode);
	return 0;
}

正常运行产生异常

0:000> g
Thu Nov  1 03:57:43.910 2018 (GMT-8): (374.80): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012fb80 ebx=0012ff68 ecx=61616161 edx=77f96dae esi=0012fba8 edi=0012ff79
eip=61616161 esp=0012fae8 ebp=0012fb08 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
61616161 ??              ???
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012fae4 77f96ba7 0012fba8 0012ff68 0012fbbc 0x61616161
0012fb08 77f96c42 0012fba8 0012ff68 0012fbbc ntdll!ZwSetIoCompletion+0x182
0012fb90 77f9ff6e 0012fba8 0012fbbc 0012fba8 ntdll!ZwSetIoCompletion+0x21d
0012ff78 004010ba 00407030 00401378 00000001 ntdll!KiUserExceptionDispatcher+0xe
0012ff80 00401378 00000001 002f0ba0 002f0bf8 image00400000+0x10ba
0012ffc0 7c581af6 02304b38 0143f6cc 7ffdf000 image00400000+0x1378
0012fff0 00000000 004012c4 00000000 000000c8 KERNEL32!OpenEventA+0x63d

根据调用栈,找到出错函数

1541074103072

分析调试该函数sub_401020

0:000> bp 40107e
0:000> g
Thu Nov  1 04:09:10.129 2018 (GMT-8): Breakpoint 0 hit
eax=00000001 ebx=7ffdf000 ecx=00000000 edx=00000000 esi=00407111 edi=0012ff79
eip=0040107e esp=0012fe88 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
image00400000+0x107e:
0040107e f7f9            idiv    eax,ecx
0:000> p
Thu Nov  1 04:09:18.723 2018 (GMT-8): (80.374): Integer divide-by-zero - code c0000094 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=7ffdf000 ecx=00000000 edx=00000000 esi=00407111 edi=0012ff79
eip=0040107e esp=0012fe88 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010246
image00400000+0x107e:
0040107e f7f9            idiv    eax,ecx
0:000> p
eax=00000001 ebx=7ffdf000 ecx=0012fbbc edx=00000000 esi=00407111 edi=0012ff79
eip=77f9ff64 esp=0012fba0 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiUserExceptionDispatcher+0x4:
77f9ff64 8b1c24          mov     ebx,dword ptr [esp]  ss:0023:0012fba0=0012fba8

在调用0040107e f7f9 idiv eax,ecx之后产生异常,系统最先调用ntdll!KiUserExceptionDispatcher处理异常,来看该函数对异常做如何处理

1541074439555

继续跟进,在调用sub_77F96BDD`出错

0:000> p
eax=00000001 ebx=0012fba8 ecx=0012fbbc edx=00000000 esi=00407111 edi=0012ff79
eip=77f9ff69 esp=0012fb98 ebp=0012ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiUserExceptionDispatcher+0x9:
77f9ff69 e86f6cffff      call    ntdll!ZwSetIoCompletion+0x1b8 (77f96bdd)
0:000> g
Thu Nov  1 04:15:30.348 2018 (GMT-8): (80.374): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012fb80 ebx=0012ff68 ecx=61616161 edx=77f96dae esi=0012fba8 edi=0012ff79
eip=61616161 esp=0012fae8 ebp=0012fb08 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
61616161 ??              ???

重新调试,继续跟进

1541074654977

再次出错

0:000> p
eax=0012fb80 ebx=0012ff68 ecx=0012fb84 edx=00000000 esi=0012fba8 edi=0012ff79
eip=77f96c3d esp=0012fb10 ebp=0012fb90 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwSetIoCompletion+0x218:
77f96c3d e83affffff      call    ntdll!ZwSetIoCompletion+0x157 (77f96b7c)
0:000> p
Thu Nov  1 04:20:19.410 2018 (GMT-8): (80.374): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012fb80 ebx=0012ff68 ecx=61616161 edx=77f96dae esi=0012fba8 edi=0012ff79
eip=61616161 esp=0012fae8 ebp=0012fb08 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
61616161 ??              ???

出错位置

1541074941488

继续跟进,找到最终出错位置

0:000> p
eax=0012fb80 ebx=0012ff68 ecx=61616161 edx=77f96dae esi=0012fba8 edi=0012ff79
eip=77f96ba5 esp=0012faec ebp=0012fb08 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwSetIoCompletion+0x180:
77f96ba5 ffd1            call    ecx {61616161}
0:000> p
Thu Nov  1 04:24:39.582 2018 (GMT-8): (80.374): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012fb80 ebx=0012ff68 ecx=61616161 edx=77f96dae esi=0012fba8 edi=0012ff79
eip=61616161 esp=0012fae8 ebp=0012fb08 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
61616161 ??              ???

分析该函数

1541075137267

ecx由最后一个参数传入

1541075187528

回溯

1541075223347

产生v2的函数sub_77F96BD6,该函数就是取得fs:0中数据

1541075322004

再次分析最先出错的函数

1541075536433

只要将shellcode或其地址放入这里,造成SEH异常,即可执行shellcode

理论求证

上述过程分析了栈溢出会造成SEH代码执行,现在来分析一下为什么

sub_401020开始时会安装SEH

.text:00401020                 push    ebp
.text:00401021                 mov     ebp, esp
.text:00401023                 push    0FFFFFFFFh
.text:00401025                 push    offset stru_4060B0
.text:0040102A                 push    offset __except_handler3
.text:0040102F                 mov     eax, large fs:0
.text:00401035                 push    eax
.text:00401036                 mov     large fs:0, esp
.text:0040103D                 sub     esp, 0D4h

结构大概是这样的

+----------------------+
|     ret_addre        |
+----------------------+
|        ebp           |
+----------------------+
|    seh something     |
+----------------------+
|    seh something     |
+----------------------+
|   __except_handler   |
+----------------------+
|      old fs:0        |
+----------------------+
|                      | <=== esp(fs:0)
+----------------------+
| local variable stack |
+----------------------+
| local variable stack |
+----------------------+

覆盖箭头位置即可,具体原理看参考

参考

windows 异常处理中的漏洞利用

Windows 系统异常处理机制的研究及应用

0day2

xinali avatar Nov 01 '18 13:11 xinali