我对ASLR非常熟悉,但是今天我听到了有关Windows中ASLR实现的一个有趣的新事实。

为了优化性能,如果进程A和B加载相同的dll,Windows将仅将其加载到物理内存一次,并且两个进程将通过共享页面共享同一实例。

这是个老新闻。但是有趣的是,进程A和B都将共享库加载到相同的虚拟地址中(为什么?)。

在我看来,任何本地攻击(例如特权升级)都可以通过以下方式轻松绕过ASLR:

1. Create a new dummy process
2. Check the address of dlls of interest (kernel32, user32 ..)
3. Attack the privileged process and bypass ASLR with the information from step 2.

我使用Olly做了一些简单的测试,发现共享库确实加载在相同的虚拟地址中。

如果确实如此,ASLR是否对本地开发毫无用处?

最佳答案

没错,ASLR不能抵御本地攻击者。它的主要目的是阻止远程利用中的硬编码地址。

编辑:我的上一个答案中的某些细节不正确,尽管上面的观点仍然成立。启用ASLR的DLL的基址实际上是以下两者的函数:(1)Windows在启动时从一组256个可能的值中选择了一个随机偏移量; (2)DLL的加载顺序,对于已知的DLL,由 session 管理器在系统启动过程中将其随机化。因此,仅知道随机偏移量不足以计算任意ASLR的DLL的基址。但是,如您所描述的,如果您能够直接观察共享内存中目标DLL的地址,则所有选择都将变为无效。

资料来源:
http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf
Windows Internals,第六版

10-06 00:35