突破DEP之理论篇

DEP(Data Execution Prevention),当程序尝试在数据页面上执行指令时,CPU将抛出异常。DEP会阻止数据页(如默认的堆页、各种堆栈页以及内存池页)执行代码
DEP有软件DEP(即SafeSEH)、硬件DEP。
要突破软件DEP参见突破SafeSEH
要突破硬件DEP可考虑:

  1. 攻击那些不支持硬件DEP的CPU - -||
  2. 攻击那些老版本的(早期的操作系统对DEP开关API的调用没有限制)、或者不会自动启动DEP的系统 - -||
  3. 攻击没有开启DEP的程序:由于Windows无法确认有些第三方插件DLL是否支持DEP,所以涉及这些DLL的程序没有开启DEP;还有一些老版本的程序需要在数据页上产生可执行代码,因此也没有开启DEP
  4. 攻击会被加载进进程内存的小控件,如:
    利用.NET控件进行攻击:.NET文件和PE文件结构相同,其.text等段会被映射到内存,so将其替换为shellcode,那么我们的shellcode就可以合法存在了
    利用Java applet进行攻击:IE浏览器可以把Java applet加载到客户端,而加载进IE进程内存后这些控件所在内存空间都具有了可执行属性

以上四条看起来有点乱,但总而言之,突破DEP的精髓在于,想方设法把shellcode放在可读可写可执行的内存位置。

利用①可实施Ret2Libc(Return-to-libc)攻击:
1)通过ret跳转到ZwSetInformationProcess函数,将DEP关闭,再转入shellcode执行 <== 不推荐使用,因为这个函数已经被废弃了
也可以:
2)通过ret跳转到VirtualProtect函数,将shellcode所在内存页设置为可执行状态,再转入shellcode执行

BOOL WINAPI VirtualProtect(
  _In_  LPVOID lpAddress,//要改变属性的内存起始地址  ==>  shellcode所在内存空间起始地址
  _In_  SIZE_T dwSize,//要改变属性的内存区域大小  ==>  shellcode大小
  _In_  DWORD  flNewProtect,//内存新的属性类型,设置为PAGE_EXECUTE_READWRITE(0x40)时该内存页为可读可写可执行  ==>  0x40
  _Out_ PDWORD lpflOldProtect//内存原始属性类型保存地址  ==>  某个可写地址
);

也可以:
3)通过ret跳转到VirtualAlloc函数,开辟一段具有执行权限的内存空间,再复制shellcode到此,最后转入执行(如果在进程内存里能找到可读可写可执行的内存,可直接跳入memcpy函数将shellcode复制于此,然后...

LPVOID WINAPI VirtualAlloc(
  _In_opt_ LPVOID lpAddress,//申请内存区域的地址,如果这个参数是NULL,系统将会决定分配内存区域的位置,并且按64KB向上取整  ==>  选择一个未被占用的内存即可
  _In_     SIZE_T dwSize,//申请内存区域的大小
  _In_     DWORD  flAllocationType,//申请内存的类型  ==>  0x00001000
  _In_     DWORD  flProtect//申请内存的访问控制类型,如读、写、执行等权限  ==>  0x00000040
);

======
一个小技巧:如果要让某个寄存器指向可读写内存,可以考虑把它指向栈空间。如:要让esi执行可读写内存,可以使用

push esp
pop esi
posted @ 2017-10-08 16:56  T_1  阅读(306)  评论(0编辑  收藏  举报