地址空间布局随机化(ASLR)是一项增加安全性的技术,攻击者发现漏洞之后开始编写exploit时如果要考虑绕过ASLR这会增加编写exploit的难度,最早是2001年Grsecurity社区(强悍的社区,直到今天还在为各种各样的加固为自由软件安全社区作出持续而杰出的贡献)针对GNU/Linux的PaX补丁中出现,后来GNU/Linux内核对用户态地址随机化的支持在2005年的2.6.12版本合并到了mainline,但直到今天内核中还是使用固定的虚拟地址。2011年的时候,Dan Rosenberg提议增加内核ASLR的功能但后来一直没有实施下去,最近Kees Cook向社区提交内核地址随机化的补丁,社区可能会在最近把这个补丁合并到mainline upstream repo里去。
绕过ASLR并不是一门新的技术,早在2002年的Phrack Issue 59中就已经有一篇论文详细的描述了原理和细节,个人认为内核空间的ASLR是非常有必要的,在内存和硬盘上隐藏内核空间地址是一个暂时的方案,比如:
测试平台:SUSE Linux Enterprise Server 11 SP2
[检查默认的内核配置]
* 从硬盘镜像上获得地址
@linuxidc:~> grep do_fork /boot/System.map-3.0.42-0.7-default ffffffff81058cd0 T do_fork
ffffffff8143959a t do_fork_idle
* 从内存中获得地址
@linuxidc:~> cat /proc/kallsyms | grep do_fork
ffffffff81058cd0 T do_fork
ffffffff8143959a t do_fork_idle
[简单的加固]
* 使用root执行:
linux-7kz0:/home/shawn # chmod o-r /boot/System.map-3.0.42-0.7-default
linux-7kz0:/home/shawn # sysctl -w kernel.kptr_restrict=1
[验证结果]
@linuxidc:~> grep do_fork /boot/System.map-3.0.42-0.7-default grep: /boot/System.map-3.0.42-0.7-default: Permission denied
@linuxidc:~> cat /proc/kallsyms | grep do_fork 0000000000000000 T do_fork 0000000000000000 t do_fork_idle
这个方法只能针对特殊定制的内核,但对于发部分GNU/Linux发行版,内核镜像都是一样的,攻击者可以通过其他方式获得固定地址,KASLR可以在一定程度上延缓攻击者的速度,但实现上可能带给内核一些副作用,有人坚决反对在内核空间实现地址随机化。