ASLR,Address Space Layout Randomization,通过加载程序的时候不再使用固定的基址,从而干扰 shellcode 定位的一种保护机制,包括映像随机化、堆栈随机化、PEB 与 TEB 随机化。ASLR 的实现也需要程序和操作系统的双重支持,但程序的支持不是必须的。
ASLR 在 XP 时代已经提出来了,但 XP 上的 ASLR 功能有限,只是对 PEB 和 TEB 进行简单的随机化处理。直到 Windows Vista 出现之后 ASLR 才真正发挥作用。
支持 ASLR 的程序会在 PE 头中设置 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE 标识。VS 2005 SP1 开始加入了 /dynamicbase 链接选项来支持 ASLR(Project - project Properties - Configuration Properties - Linker - Advanced - Randomized Base Address)。
映像随机化
对程序映像的虚拟地址进行随机处理,这个地址是在系统启动时确定的,重启后会变化。映像随机化可以通过注册表来设置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\MoveImages DWORD: 0 Disabled DWORD: -1 Force Enabled DWORD: other Normal
映像随机化使得通过的跳板指令无效。但映像随机化只对加载基址的前两个字节做了随机处理,各模块入口点的低位 2 字节不变。
堆栈随机化
堆栈随机化中,其基址是在每次加载程序时确定的。
jmp esp 和 heap spray 的运用使得堆栈随机化对溢出利用的影响有限。
PEB、TEB 随机化
XP SP2 中引入 PEB、TEB 的随机化,在此之前固定基址: PEB:0x7FFDF000,TEB:0x7FFDE000,获取当前 PEB 和 TEB 的参考代码如下:
1 #include "stdafx.h" 2 3 int _tmain(int argc, _TCHAR* argv[]) 4 { 5 unsigned int teb; 6 unsigned int peb; 7 __asm{ 8 mov eax,FS:[0x18] 9 mov teb,eax 10 mov eax,dword ptr[eax+0x30] 11 mov peb,eax 12 } 13 printf("peb: %#x\nteb: %#x\n",peb,teb); 14 getchar(); 15 return 0; 16 }
PEB 和 TEB 随机化效果不是很好,而且溢出利用时还有其它方法获得这两个值。