zoukankan      html  css  js  c++  java
  • 基础知识 SafeSEH DEP ASLR SEHOP

    大多是0day书上抄的

    1.SafeSEH

      机制:

      首先:内存中有SEH表的备份(加密过的)

       在调用异常出来函数前,RtlDispatchException()函数中的行为:

      Ⅰ.检查异常处理链是否位于当前程序的栈中,如果不在当前栈中,程序将终止异常处理函数的调用。

      Ⅱ.检查异常处理函数指针是否指向当前程序的栈中,如图所示。如果指向当前栈 中,程序将终止异常处理函数的调用。

          

      Ⅲ.在前面两项检查都通过后,程序调用一个全新的函数 RtlIsValidHandler(),来对异常处 理函数的有效性进行验证

       RtlIsValidHandler()行为:

      (1)判断程序是否设置了 IMAGE_DLLCHARACTERISTICS_NO_SEH 标识。如果设置了这个标识,这个程序内的异常会被忽略。

          所以当这个标志被设置时,函数直接返回校验失败。

      (2)检测程序是否包含安全 S.E.H 表。如果程序包含安全 S.E.H 表,则将当前的异常处理 函数地址与该表进行匹配,匹配成功则返回校验成功,匹配失败则返回校验失败。

      (3)判断程序是否设置 ILonly 标识。如果设置了这个标识,说明该程序只包含.NET 编译 人中间语言,函数直接返回校验失败。

      (4)判断异常处理函数地址是否位于不可执行页(non-executable page)上。当异常处理函 数地址位于不可执行页上时,校验函数将检测 DEP 是否开启,如果系统未开启 DEP 则返回校 验成功,否则程序抛出访问违例的异常。

         如果异常处理函数的地址没有包含在加载模块的内存空间,校验函数将直接进行 DEP 相 关检测,函数依次进行如下校验。     

        ①判断异常处理函数地址是否位于不可执行页(non-executable page)上。当异常处理函 数地址位于不可执行页上时,

          校验函数将检测 DEP 是否开启,如果系统未开启 DEP 则返回校 验成功,否则程序抛出访问违例的异常。

        ②判断系统是否允许跳转到加载模块的内存空间外执行,如果允许则返回校验成功,否 则返回校验失败。

        

       绕过检测的方法:

       (1)异常处理函数位于加载模块内存范围之外,DEP 关闭。

        (2)异常处理函数位于加载模块内存范围之内,相应模块未启用 SafeSEH(安全 S.E.H 表为空),同时相应模块不是纯 IL。

        (3)异常处理函数位于加载模块内存范围之内,相应模块启用 SafeSEH(安全 S.E.H 表不为空),异常处理函数地址包含在安全 S.E.H 表中。

        (4)  异常处理函数指向堆空间(原理不清楚)

        

     2.DEP

      机制:

      将内存页标志为不可执行(比如说栈,.data区等)

        检测:DEP是否开启的标志

          _KEXECUTE_OPTIONS{

          ExecuteDisable :1bit        ;DEP 开启时 ExecuteDisable 位被置 1

          ExecuteEnable :1bit         ;DEP 关闭时 ExecuteEnable 位被置 1

          DisableThunkEmulation :1bit

          Permanent :1bit

          ExecuteDispatchEnable :1bit

          ImageDispatchEnable :1bit

          Spare :2bit  }

       绕过:

      1.Ret2Libc

        解释:在加载的内存中找具有可读可写可执行属性的内存,在内存中搜索相应的指令(如pop retn),把指令地址填入栈中覆盖原跳转地址,使得程序跳到找的指令处执行。执行完再跳回到栈内的下一条执行。

        例如:

        ①利用ZwSetInformationProcess函数修改DEP标志

         方法:ntdll.dll中,LdrpCheckNXCompatibility 函数中里面刚好会调用ZwSetInformationProcess地址,设置好前置条件就可以跳过去调用它,关掉DEP(前提是LdrpCheckNXCompatibility中没用GS)

        ②同理利用VirtualProtect修改指定地址的内存属性,或者VirtualAlloc+memcpy,把shellcode拷贝过去。

        难点:构建参数,是动态获取的,必须通过巧妙的指令,使得参数的地址刚好可以调用shellcode的地址

          必须保证调用函数前参数刚好在ESP

         一些指令: 

          pop ret
          push esp pop ebp ret
          call [esp+-n]
          call [ebp+-n]
          retn :加esp
          push esp pop esi retn == pop eax retn + push esp jmp eax (eax里面是 pop esi retn 地址)

          ③利用内存中已存在的拥有可读可写可执行属性内存。

    3.ASLR

        机制:

       1.内存映射地址随机化(每次系统重启时改变)

       2.PEB,TEB地址随机化

      应对:

        1.利用未随机化的模块作为跳板

        2.栈内相对偏移未改变,可以修改地址的最后两个字节使得有限度的跳转

        3.先跳到某个空闲位置,如0x0C0C0C0C(自己设置),使用堆喷射覆盖

    4.SEHOP

      机制:在异常处理前,遍历SEH链,直到最后一项(终极异常处理)

                      

         检查流程:

          

      

        应对:

        注:不考虑SafeSEH,ALSR等其他保护

        伪造终极SEH(必须四字对齐且在栈内) 使得当前栈中异常链的指针指向伪造的SEH(end of SEF chain,保存0xFFFFFFFF)

     

    5.利用方式总结:

      栈溢出:retn,ESH,虚函数,总之一切带跳转的都能利用,根据实际情况。

      

      

      

     

        

  • 相关阅读:
    《你不知道的javascript》读书笔记2
    你不知道的console调试
    《你不知道的javascript》读书笔记1
    使用js做LeetCode
    用装饰器来进行登录验证
    python 解压序列
    pycharm 的live_template的使用
    faker 库的使用
    Python常用内置类和常用内置函数汇总
    迭代器 ,生成器(生成器函数/生成器表达式)
  • 原文地址:https://www.cnblogs.com/jf-blog/p/12375192.html
Copyright © 2011-2022 走看看