异常的保护机制

以栈作为基础的SEH本身具有很大的危险性,我们可以利用各种手段对栈上SEH节点进行覆盖重写,再次执行异常处理操作时就会将执行权给到了我们用来覆盖的函数上,这实际上在以前是很常见的windows栈溢出手段,当然,除了这种方法外还有许许多多的利用手段,可见这样的异常处理机制还是不够完善的。为了解决这些问题,微软逐步加入了Safe SEH、SEHOP、VCH等来弥补。

Safe SEH

SafeSEH又叫做软件DEP,是一种在软件层面实现的对SEH的保护机制,它需要操作系统和编译器的双重支持,在vs2013及以后的版本中会自动启用 /SafeSEH 链接选项来使用SafeSEH。也正是因为该项技术使得以往简单的覆盖异常处理句柄的漏洞利用几乎失效了

在加载PE文件时,SafeSEH将定位合法的SEH表的地址(如果该映像不支持SafeSEH的话则地址为0),然后是用共享内存中的一个随机数进行加密处理,程序中所有的异常处理函数的地址提取出来汇总放入SEH表,并将该表放入程序映像中,还会将将加密后的SEH函数表地址,IMAGE的开始地址,IMAGE的长度,合法SEH函数的个数,作为一条记录放入ntdll(ntdll模块是进行异常分发的模块)的加载模块数据内存中,每次调用异常处理函数时都会进行校验,只有二者一致才能够正常进行,该处理由RtlDispatchException() 开始,首先会经历两次检查,分别是:

  • 检查异常处理链是否在当前的栈中,不是则终止
  • 检查异常处理函数的指针是否指向栈,是则终止

通过两次检查后会调用RtlIsValidHandler() 来进行异常的有效性检查,08年的black hat给出了该函数的细节

BOOL RtlIsValidHandler( handler )
{
    if (handler is in the loaded image)      // 是否在loaded的空间内
    {
        if (image has set the IMAGE_DLLCHARACTERISTICS_NO_SEH flag) //是否设置了忽略异常
            return FALSE;
        if (image has a SafeSEH table)       // 是否含有SEH表
            if (handler found in the table)  // 异常处理函数地址是否表中
                return TRUE;
            else
                return FALSE;
        if (image is a .NET assembly with the ILonl    y flag set)
            return FALSE;
    }

    if (handler is on non-executable page)   // handler是否在不可执行页上
    {
        if (ExecuteDispatchEnable bit set in the process flags) //DEP是否开启
            return TRUE;
        else
            raise ACCESS_VIOLATION;
    }

    if (handler is not in an image)          // handler是否在未加载空间
    {
        if (ImageDispatchEnable bit set in the process flags) //设置的标志位是否允许
            return TRUE;
        else
            return FALSE;
    }
    return TRUE;                             /s/ 允许执行异常处理函数
}

代码中的ExecuteDispatchEnable和ImageDispatchEnable位标志是内核KPROCESS结构的一部分,这两个位用来控制当异常处理函数在不可以执行内存或者不在异常模块的映像(IMAGE)内时,是否执行异常处理函数。这两个位的值可以在运行时修改,不过默认情况下如果进程的DEP被关闭,则这两个位置1,如果进程的DEP是开启状态,则这两个位被置0。

通过源码我们可以看出,RtlIsValidHandler() 函数只会在以下几种情况执行异常处理函数

  • 在进程的DEP是开启的情况下

    • 异常处理函数和进程映像的SafeSEH表匹配且没有NO_SEH标志。
    • 异常处理函数在进程映像的可执行页,并且没有NO_SEH标志,没有SafeSEH表,没有.NET的ILonly标志。
  • 在进程的DEP关闭的情况下
    • 异常处理函数和进程映像的SafeSEH表匹配没有NO_SEH标志。
    • 异常处理函数在进程映像的可执行页,并且没有NO_SEH标志,没有SafeSEH表,没有.NET的ILonly标志。
    • 异常处理函数不在当前进程的映像里面,但是不在当前线程的堆栈上。

SEHOP

全称为Structured Exception Handler Overwrite Protection(结构化异常处理覆盖保护),这是专门用来检测SEH是否被劫持的一项技术,我们在上面的RltDispatchExeption实际上已经提到过一些SEHOP的检测过程了,这里我们来具体说一说

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession Managerkernel

你可以在该表项下找到DisableExceptionChainValidation的键,它标示着你的计算机是否开启了该功能。

我们再次回到RltDispatchExeption来看看它的具体操作,代码来自Vistasp1

// Skip the chain validation if the DisableExceptionChainValidation bit is set
if (process_flags & 0x40 == 0)
{
    // Skip the validation if there are no SEH records on the linked list
    if (record != 0xFFFFFFFF)
    {
        // Walk the SEH linked list
        do
        {
            // 1、The record must be on the stack
            if (record < stack_bottom || record > stack_top)
                goto corruption;

            // 2、The end of the record must be on the stack
            if ((char*)record + sizeof(EXCEPTION_REGISTRATION) > stack_top)
                goto corruption;

            // 3、The record must be 4 byte aligned
            if ((record & 3) != 0)
                goto corruption;

            handler = record->handler;
            // 4、The handler must not be on the stack
            if (handler >= stack_bottom && handler < stack_top)
                goto corruption;

            record = record->next;
        } while (record != 0xFFFFFFFF);

        // End of chain reached
        // Is bit 9 set in the TEB->SameTebFlags field? This bit is set in
        // ntdll!RtlInitializeExceptionChain, which registers
        // FinalExceptionHandler as an SEH handler when a new thread starts.
        if ((TEB->word_at_offset_0xFCA & 0x200) != 0) {
            // 5、The final handler must be ntdll!FinalExceptionHandler
            if (handler != &FinalExceptionHandler)
                goto corruption;
        }
    } // end if (record != 0xFFFFFFFF)
}

大家可自行阅读代码,概括来说主要是对以下几点的检测:

  • SEH节点必须在栈上
  • SEH节点的Handle必须不在栈上
  • 最后的SEH节点的Handle必须是ntdll!FinalExceptionHandler,也就是咱们上面说的异常的最后一站
  • 最后的SEH节点的Next指针必须为0xffffffff

原文地址:https://www.cnblogs.com/yilang/p/12394656.html

时间: 2024-10-02 06:32:01

异常的保护机制的相关文章

【安全健行】(6):Windows漏洞保护机制

2015/5/21 11:07:55 之前我们一直在Linux平台上分析漏洞,那是因为对于绝大多数Hacker获得一个Linux平台更加容易,而且主流的服务器系统基本也都是Linux/Unix的:另外一个好处就是Linux提供了用户自定义的强大功能,我们可以根据需要编译汇编程序代码,关闭相应的安全保护机制,便于我们的研究学习. 然而现实中有影响力的漏洞大多是基于Windows系统,因此这节我们来介绍下Winodws系统上是安全保护机制,至于Windows上的漏洞分析,我们会在之后的恶意代码分析章

各种保护机制绕过手法

一.绕过GS编译选项 ●原理:通过VC++编译器在函数前后添加额外的处理代码,前部分用于由伪随机数生成的cookie并放入.data节段,当本地变量初始化,就会向栈中插入cookie,它位于局部变量和返回地址之间 ●绕过方法: 1.猜测/计算cookie Reducing the Effective Entropy of GS Cookies:http://www.uninformed.org/?v=7&a=2&t=html 至从覆盖SEH的方法出现后,这种方法目前已基本不用了,它没有后面

Python之异常抛出机制

异常抛出机制 : 常见的Python异常:

完成这个例子,说出java中针对异常的处理机制。

有一个类为ClassA,有一个类为ClassB,在ClassB中有一个方法b,此方法抛出异常,在ClassA类中有一个方法a,请在这个方法中调用b,然后抛出异常.在客户端有一个类为TestC,有一个方法为c ,请在这个方法中捕捉异常的信息.完成这个例子,请说出java中针对异常的处理机制. [java] view plaincopy package com.itheima; import java.io.IOException; /** *第6题:有一个类为ClassA,有一个类为ClassB,

二进制的保护机制

0x00 checksec 这里主要讲的是CTF中linux下的ELF二进制文件的保护机制.在linux中有一个脚本checksec命令可以查看当前二进制文件的保护机制.任意安装一款gdb插件都会把checksec脚本包含进来. 在gdb中执行: gdb> checksec test Canary : No NX : Yes PIE : No Fortify : No RelRO : Partial 直接在shell中执行: $ checksec test Arch: i386-32-littl

Android中的软件安全和逆向分析[二]—apk反破解技术与安全保护机制

在Android应用开发中,当我们开发完软件之后,我们不希望别人能够反编译破解我们的应用程序,不能修改我们的代码逻辑.实际上,在应用程序的安全机制考虑中,我们希望自己的应用程序安全性高,通过各种加密操作等来增大竞争对手的反编译破解成本.设想,竞争对手开发一个同样的应用程序需要10天,而破解我们的软件程序需要100天,那么势必会打消黑客程序员破解我们应用程序的念头.如何增加对手的破解成本,就需要考验我们应用程序的安全性有多高,加密技术有多强.一个优秀的应用程序,不仅能为用户带来利益,同时也能保护自

GCC中的堆栈保护机制

以堆栈溢出为代表的缓冲区溢出已成为最为普遍的安全漏洞,由此引发的安全问题比比皆是.我们知道攻击者利用堆栈溢出漏洞时,通常会破坏当前的函数栈.在gcc中,通过编译选项可以添加 函数栈的保护机制,通过重新对局部变量进行布局来实现,达到监测函数栈是否非破坏的目的. gcc中有3个与堆栈保护相关的编译选项 -fstack-protector:启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码. -fstack-protector-all:启用堆栈保护,为所有函数插入保护代码. -fn

CPU保护机制

如果程序可以直接跟内核交互,那么操作系统会变的不稳定.因此有一个机制会讲内核和程序隔开. 一般的CPU有4层保护机制. 第0环,特权级别.只有内核才能运行到第0级别, 最外环,其他程序运行. 所以在内存上也是这样 CPU保护机制

操作系统学习(七) 、保护机制概述

保护机制是可靠运行多任务环境所必须的.它可以用于保护各个任务免受互相之间的干扰.在软件开发的任何阶段都可以使用段级和页级保护来协助寻找和检测设计问题和错误.当程序对错误内存空间执行了一次非期望的引用,保护机制可以阻止这种操作并且报告此类事件. 保护机制可以被用于分段和分页机制.处理器寄存器的2个比特位定义了当前执行程序的特权级,称为当前特权级CPL.在分段和分页地址转换过程中,处理器将对CPL进行验证. 通过设置控制寄存器CR0的PE标志(位0)可以让处理器工作在保护模式下,从而也就开启了分段保