『FreeBuf』永远修复不完的Linux本地ASLR漏洞


『FreeBuf』永远修复不完的Linux本地ASLR漏洞
本文插图
介绍ASLR , 应为全称为Address Space Layout Randomization , 即地址空间布局随机化 。 它是一种概率性安全防御机制 , 由PaX团队于2001年正式提出 , 并在2005年开始引入到Linux内核之中 。 ASLR能够在每次运行可执行文件的时候通过基地址随机映射的方式来为其随机分配地址空间 。 ASLR存在的目的 , 就是为了防止那些需要了解内存地址来利用内存崩溃漏洞的攻击行为 。
在此之前 , 内存崩溃漏洞的成功利用需要来了解硬编码的内存地址 , 以便攻击者获取到可执行指令的地址并实现任意代码执行 , 或破坏关键的程序数据 。 ASLR最初是用来抵御和防范远程攻击者的 , 因为攻击者需要获取到目标设备的内存地址才能执行攻击 , 那么对于远程攻击者来说 , 实现掌握的关于内存地址的信息肯定不会很多 。
历史回顾对于本地攻击者来说 , /proc/[pid]/一直都存在各种问题 , 而且一般都是信息泄露漏洞的主要来源 。 2009年 , 谷歌安全团队的Tavis Ormandy和Julien Tinnes曾在CanSecWest就Linux ASLR这个话题进行过一次演讲【PDF】 , 并在演讲中演示了如何通过/proc/[pid]/stat和/proc/[pid]/wchan来获取目标进程中的指令指针以及堆栈指针等信息 , 而这些信息可以帮助攻击者重建目标进程的地址空间布局 。
十年后的2019年4月3日 , 一个针对v4.8以下版本Linux内核的漏洞利用代码被曝光 , 而这个漏洞同样利用了/proc/[pid]/stat来获取之前提到的指令指针和栈指针 。 因为fs/binfmt_elf.c中的load_elf_binary调用install_exec_creds的时机太晚了 , 可执行文件已经被映射到地址空间 , 然后才设置访问凭证 , 因此攻击者将能够绕过ptrace_may_access检的查 , 而这个检查机制正是为了修复Tavis和Julien提出的攻击而引入的 。 攻击者只要在install_exec_creds调用前使用read来读取/proc/[pid]/stat , 就可利用这一个竞争条件漏洞了 。
2019年4月25日 , 就在CVE-2019-11190被曝光之后 , SUSE Linux的安全工程师也在Openwall的oss-sec列表上发布了一个已被修复了的安全问题 , 版本号低于3.18的内核版本都会受到该漏洞的影响 。 这个漏洞是一个ASLR绕过漏洞 , 由于/proc/[pid]/maps伪文件的权限检查放在了read , 而不是open , 这个伪文件中包含当前映射的内存区域及其访问权限 。
02496000-024b7000 rw-p0000000000:000[heap]7f508bd4b000-7f508beec000 r-xp0000000008:047605352/lib/x86_64-linux-gnu/libc.so7f508beec000-7f508c0ec000 ---p001a100008:047605352/lib/x86_64-linux-gnu/libc.so7f508c0ec000-7f508c0f0000 r--p001a100008:0476053527f508c0f0000-7f508c0f2000 rw-p001a500008:0476053527f508c0f2000-7f508c0f6000 rw-p0000000000:0007f508c0f6000-7f508c117000 r-xp0000000008:047605349/lib/x86_64-linux-gnu/ld.so7f508c164000-7f508c2ed000 r--p0000000008:04800126/usr/lib/locale/locale-archive7f508c2ed000-7f508c2f0000 rw-p0000000000:0007f508c2f2000-7f508c316000 rw-p0000000000:0007f508c316000-7f508c317000 r--p0002000008:047605349/lib/x86_64-linux-gnu/ld.so7f508c317000-7f508c318000 rw-p0002100008:0476053497f508c318000-7f508c319000 rw-p0000000000:000ffffffffff600000-ffffffffff601000 r-xp0000000000:000[vsyscall]从v2.6.22开始 , 如果你无法将ptrace附加到某进程下的话 , Linux内核就不允许它读取/proc/[pid]/maps , 这也就意味着非特权用户将无法读取映射的伪文件 。


推荐阅读