通过使用共享页面确定库地址绕过 Windows ASLR
Posted
技术标签:
【中文标题】通过使用共享页面确定库地址绕过 Windows ASLR【英文标题】:Bypassing Windows ASLR by determining the library address using shared pages 【发布时间】:2015-07-04 03:34:51 【问题描述】:我对 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 对本地开发没用吗?
【问题讨论】:
如果 DLL 将被加载到不同的地址,那么它必须被重新定位并且 RAM 页面不能再被共享。 ASLR 的主要观点是它在您机器上的加载位置与它在我的机器上的加载位置不同。当您重新启动时,它也会有所不同。 据我记忆.. 每个进程都有一个表,将虚拟页面的地址转换为物理页面。每个进程都有自己的唯一表。 Microsoft 不能一次将 DLL 加载到物理内存中,并为每个进程将 DLL 加载到不同的虚拟地址中吗? 不,重定位会更改代码,因此一份副本不再有效。 【参考方案1】:你是对的,ASLR 对本地攻击者几乎没有防御作用。它主要用于阻止远程攻击中的硬编码地址。
编辑:我之前的回答中的一些细节是不正确的,尽管上面的观点仍然成立。启用 ASLR 的 DLL 的基地址实际上是以下两者的函数: (1) Windows 在启动时从一组 256 个可能值中选择的随机偏移量; (2)加载DLL的顺序,对于已知的DLL,在系统启动期间由会话管理器随机化。因此,仅知道随机偏移量不足以计算任意 ASLR 的 DLL 的基地址。但是,如果您能够直接观察共享内存中目标 DLL 的地址,正如您所描述的,那么无论如何,所有的赌注都没有了。
来源: http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf Windows 内部,第 6 版
【讨论】:
非常有趣..这种“技术”是在野外使用的吗?我读过一些关于本地漏洞利用的案例研究,但从未见过攻击者使用这种技术.. @MichaelEngstler 道歉,我相信我在那个细节上完全错了。我已经修改了我的答案以反映。以上是关于通过使用共享页面确定库地址绕过 Windows ASLR的主要内容,如果未能解决你的问题,请参考以下文章
Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)