S.E.H终极防护,在SafeSEH的基础上检查异常处理链的完整性,即在执行异常处理函数之前,SEHOP会检查SEH链上最后一个异常处理函数是否为系统固定的终极异常处理函数。
如果是则说明这条S.E.H链未被破坏,程序可以去执行当前的异常处理函数;否则说明S.E.H链被破坏,可能发生了S.E.H覆盖攻击,程序出错。
支持Windows vista sp1、Win7、Windows server 2008。
除了windows server 2008默认开启SEHOP,其他系统是默认关闭的。启用方式:
1.打补丁(不适用vista和win7)
2.手工在注册表中找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel下面的DisableExceptionChainValidation项(没有的话新建),将该项设为0即可启用SEHOP。
0x00 利用未启用SEHOP的模块
微软在编译器没有提供禁用SEHOP的选香港,但出于兼容性的考虑仍然会对一些程序禁用SEHOP,如经过Armadilo加壳的软件。操作系统会根据PE头中的MajorLinkerVersion和MinorLinkerVersion两个选型来判断是否为操作系统禁用SEHOP。我们可以把这两个选项分别设置为0x53和0x52来模拟经过Armadilo加壳的程序。
修改PE文件可以使用CFF Explorer。
剩下的工作和直接打SafeSHE基本没差,主要注意shellcode要用win7的。
0x01 伪造SEH链表
主要需要考虑到:
1.pop pop retn之后会返回到shellcode之前一段位置执行,fake ptr to next SEH和fake ptr to SEH func两个指针都会被作为机器码执行。这就对填入的fake ptr to next SEH地址有一定要求——如果表示SEH end地址的双字对应的机器码可以正确执行且不影响后面的shellcode,那么fake ptr to next SHE可以直接填入SEH end的地址,从而省去再伪造一个SEH节点的步骤;否则必须给fake ptr to next SEH这里选择一个合适的地址,并在该地址处构造指向SEH end的指针。
2.实际环境中fake ptr to SHE func和shellcode之间的位置会被程序本身的流程填入数据,如果shellcode紧跟在fake ptr to SEH func之后,那么shellcode就会被破坏而无法执行,所以必须结合实际情况填充一段nops。