ASLR在Windows Vista后才真正发挥作用,它包含:映像随机化①、堆栈随机化②、PEB和TEB随机化③。
①、③的随机化效果其实不太好;②确实可以防范精确攻击,但鉴于有jmp esp
、heap spray等不需要精确跳转的攻击手法,因而防范作用有限。
突破ASLR的方法:
- 攻击未启用ASLR的模块
- 利用部分覆盖进行定位内存地址:
虽然此时栈里的函数ret_add、异常处理函数指针、虚表指针都是随机处理后的地址,但①只是对映像加载基址的前2个字节做随机化处理。所以如果只覆盖地址的最后一两个字节,就可以在一定范围内控制程序。
此法对应的shellcode布局示例:
- 利用heap spray大量申请内存,占领内存中的0x0C0C0C0C,并在这些内存里存放nop和shellcode,让程序转入0x0C0C0C0C执行。
该法的理论基础是,虽然每次进程起始地址都会变,但第一个内存块始终在内存低址徘徊。 - 利用Java applet heap spray大量申请内存,虽然JVM对其申请堆大小有限制(最多100MB),但这100MB的空间在系统重启后始终会有一定交集,这为对抗ASLR提供了可能性(我们只要把shellcode放于内存交集里的0x0X0X0X0X处,则每次系统重启后,shellcode照样能正常执行)
- 直接修改PE头让.NET控件禁用ASLR