写在前面:
本篇博客为本人原创,但非首发,首发在先知社区
原文链接:
https://xz.aliyun.com/t/13924?time__1311=mqmxnQ0%3DqGwx2DBqDTlpzeG%3DKT8qQTID&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F74789
各位师傅有兴趣的话也可以去先知社区个人主页逛逛(个人昵称:Shad0w_2023)。
我们前面已经详细介绍过GS,SafeSEH,和DEP保护机制,大家想一想,如果没有开启任何保护,如果程序存在漏洞我们是不是很容易攻击成功?就算开了前面已经介绍过的保护,我们也有很容易的方法突破这些保护,进而完成攻击。
那么我们再次站在开发者的角度,我们如何制定一种保护机制,从而让攻击很难完成呢?站在开发者的角度,相信我们能够更容易了解到ASLR保护机制,我们接下来就来看看ASLR:
一.ASLR保护机制详解
攻击者在攻击的时候,是瞄准了进程内的一个地址(shellcode起始地址或者是跳板地址),从而进行攻击的,那我们有没有办法让攻击者的这个地址无效呢?
我们知道在进程加载的时候,有自己的虚拟内存空间,首先将自己的PE文件加载入内存,然后加载所需模块的PE,而这些地址都是固定的,从而让攻击者瞄准了去攻击,所谓惹不起我们还躲不起吗?我们想办法,让这些地址在加载的时候随机化,是不是就可以让攻击者的地址无效了呢?
实际上ASLR保护机制也就是这样做的:我们知道在PE文件中有一个ImageBase字段,标识了程序加载基址,exe通常都是一个进程加载的第一个文件,所以通常不需要重定位,而DLL需要重定位。我们开启了ASLR保护机制之后,实际上就是ImageBase随机化了。
实际上,ASLR保护机制在Windows XP版本的时候就已经出现了,但是那时候只是对PEB和TEB做了简单的随机化处理,并没有对模块的加载基址随机化。
与SafeSEH类似,ASLR的实现也需要操作系统和应用程序的双重支持,而其中,应用程序的支持不是必须的。
我们来看看PE文件结构:
我们可以看到在程序拓展头里面有一个字段:IMAGE_DLL_CHARACTERISTICS_SYNAMIC_BASE
,这个字段就标识了其是否支持ASLR。
实际上,ASLR是对很多地方都做了随机化,我们来详细看看:
-
映像基址随机化:
当PE文件映射到内存的时候,对其加载的虚拟地址进行随机化处理,注意这个地址实在系统启动时确定的,在重启系统后,这个地址就会变化。
在前面的介绍中,我们都知道为了兼容性而牺牲了很多安全性,让攻击者有了可乘之机,而对于ASLR保护机制,出于兼容性考虑,也是做了一些操作:
在注册表中,可以设定映像随机化的工作模式:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\MoveImage
,在这个注册表项下可以设置,当设置为0时,映像随机化将被禁用、设置为-1时,可以强制对可随机化的映像进行处理,无论是否设置IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
标识、设置为其他值时,标识映像基址随机化正常工作。
通常情况下,我们使用的计算机是没有MoveImage表项的,大家可以手动建立一个名称为MoveImage的表项,类型为DWORD:
-
堆栈随机化
前面文章介绍过的绕过保护的方式,我们可以将shellcode写道堆栈上,然后劫持程序执行流,让其去执行ShellCode,ASLR保护基址将堆栈地址也做了随机化,这样攻击者的目标地址就会变成了无效地址。与映像基址随机化不同的是,堆栈随机化是在程序启动的时候确定的,也就是说,在任何两次启动一个