通过使用共享页面确定库地址绕过 Windows ASLR

Bypassing Windows ASLR by determining the library address using shared pages

我对 ASLR 相当熟悉,但今天我听到一个关于 ASLR 在 Windows 中实现的有趣的新事实。

为了优化性能,如果进程 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,会话管理器在系统启动期间将其随机化。因此,仅知道随机偏移量不足以计算任意 ASLR'd DLL 的基地址。但是,如果您能够像您所描述的那样直接观察共享内存中目标 DLL 的地址,那么所有赌注都将失败。

来源: http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf Windows 内幕,第 6 版