背景

根据官方介绍,OverlayFs漏洞允许Ubuntu下的本地用户获得root权限。这个漏洞是Ubuntu系统中的特定问题,在该问题中,未正确验证关于用户namespace文件系统功能的应用程序。由于Ubuntu附带了一个允许非特权的Overlayfs挂载的补丁,结合这个补丁挂载Overlayfs可以权限逃逸,达到权限提升的目的。

影响版本

  • Ubuntu 20.10

  • Ubuntu 20.04 LTS

  • Ubuntu 18.04 LTS

  • Ubuntu 16.04 LTS

  • Ubuntu 14.04 ESM

漏洞复现

首先查看内核版本,为受影响版本编译exploit后执行,提权成功。如下图所示:

相关介绍

(1)虚拟文件系统

为支持各种本机文件系统,且在同时允许访问其他操作系统的文件,Linux内核在用户进程(或C标准库)和文件系统实现之间引入了一个抽象层。该抽象层称之为虚拟文件系统(Virtual File System)简称VFS,如下图所示:

VFS为所有的文件系统提供了统一的接口,对每个具体文件系统的访问要通过VFS定义的接口来实现。VFS抽象了几个重要的结构:super_block,dentry,inode,file,通过这些结构将一个真实的文件系统抽象到内存中,从而通过管理这些对象对文件系统进行操作。

(2)Overlay文件系统

OverlayFS是一个面向Linux的文件系统服务,其实现一个面向其他文件系统的联合挂载。它于2014年被合并到Linux内核的3.18版本。OverlayFS的主要机制涉及到两个文件系统,提供同一名称的目录时,目录访问合并。除此之外,OverlayFS呈现其中一个所产生的对象,“上层”文件系统优先。OverlayFS与其他覆盖型文件系统不同,OverlayFS合并的目录子树不一定是来自不同的文件系统。效果如下图所示:

其挂载文件的基本命令如下:

mount -t overlay overlay -o lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work merged。

其中“lower1:lower2:lower3”表示不同的lower层目录,不同的目录使用“:”分隔,层次关系依次为lower1 > lower2 > lower3(注:多lower层功能支持在Linux-4.0合入,Linux-3.18版本只能指定一个lower dir),然后upper和work目录分别表示:upper层目录和文件系统挂载后,用于存放临时和间接文件的工作基目录(work base dir),最后的merged目录就是最终的挂载点目录。若一切顺利,在执行以上命令后,overlayfs就成功挂载到merged目录下了。

(3)capabilitiy

为了进行权限检查,Linux系统将进程分为了两类:privileged进程(effective UID为0)和 unprivileged 进程(effective UID为非0)。privileged进程可以绕过所有的内核权限检查,而unprivileged 进程要进行严格的权限检查。从2.2版本的内核开始,linux对权限进行了细分,分为多种不同的权限,称之为capability。capability可以作用在进程上,也可以作用在程序文件上。目前,Linux系统上实现了37种capability。

每个进程都有五个capability集合:Permitted,Inheritable,Effective,Ambient,Bounding。文件的capability保存在文件的扩展属性security.capability中。文件有三个capabilitiy集合:Permitted,Inheritable,Effective。文件的capability和进程的capability一起来决定在执行execve后,进程的capability。

漏洞原理

(1)OverlayFS挂载

通常情况下,挂载文件系统是需要特权的,但是在Ubuntu系统中,普通用户便可以挂载OverlayFS。以5.4.0版本内核主线代码为例,ovl_fs_type结构体定义如下图所示:

以Ubuntu20.04的内核补丁linux_5.4.0-26.30.diff为例,补丁如下图所示:

添加了fs_flags数据域,并设置为FS_USERNS_MOUNT,表示将允许一个普通用户在低权限用户命名空间中mout一个overlayfs文件系统。当去mount一个overlayfs文件系统时,调用路径如下图所示:

会调用到do_new_mount()函数,该函数是创建一个新的mount,并将其放入namespace树中,实现代码如下图所示:

行2792,获取要挂载的文件系统类型,这里是overlay。然后就是进行capabilitiy校验,如下图所示:

由于fs_flags被设置为FS_USERNS_MOUNT,进入ns_capable()函数,最后通过检验后,如下图所示:

并且设置current->flags为PF_SUPERPRIV,即在当前进程上设置超级权限,并返回ture。所以通过挂载overlay文件系统,当前进程具备了超级权限。

(2)权限逃逸

该漏洞是在setxattr()函数中产生的,当对文件扩展属性的capabilitiy进行设置时,权限校验不彻底。下面是"SSD Secure Disclosure"披露的Exp执行情况,调用路径如下图所示:

这里pathname为“./ovlcap/merge/magic”,行468,调用cap_convert_nscap()函数,将要设置的cap转换到nscap中,如下图所示:

进入cap_convert_nscap()函数,进行相关检测后,如果是capabilitiy版本2,则直接调用ns_capable()进行检验,根据注释可知,如果user有超级权限,直接写入并返回。

毫无疑问,这里肯定是检验通过的。打印关键内存,如下图所示:

寄存器rax为0x1,表示返回ture。因为当前访问的inode属于overlay文件系统的。从cap_convert_nscap()函数正确返回后,随即进入vfs_setxattr()函数,这是第一次进入。接下来就是分发到overlay文件系统对应的ovl_xattr_set()函数中,调用路径如下图所示:

看ovl_xattr_set()函数的部分实现代码,获取upperdentry和realdentry,如下图所示:

获取后,打印upperdentry和realdentry内存,如下图所示:

根据overlay文件系统特性,这里的upperdentry和realdentry应该是“./ovlcap/upper”目录下的magic的目录项,打印内存可知,如下图所示:

确定真实的dentry后,第二次调用vfs_setxattr()函数,如下图所示:

此时的dentry是属于ext3文件系统的,打印内存可知,如下图所示:

到此可知,实际上是对ext3文件系统下的“./ovlcap/upper/magic”进行设置cap。权限逃逸过程如下图所示:

漏洞利用分析

"SSD Secure Disclosure"官方已经披露了相关Exp,具体分析如下:

这里定义后面挂载overlay文件系统的文件夹名称:

并自定义xmkdir函数创建这些文件夹:

然后获取当前用户的uid和gid:

创建新的user namespace,因为overlayfs mount需要CAP_SYS_MOUNT能力,因此需要新建一个NEWUSER的namespace,这样就具有CAP_SYS_MOUNT,

CLONE_NEWNS和CLONE_NEWUSER定义:

用当前用户的uid和gid等改写/proc/self下的对应文件,并且用该权限下的namespace挂载overlayfs,前面简介说了,由于ubuntu的补丁存在,该操作是合法的。

对应目录下可以看到我们修改了的文件,通过/proc/self/exe可以找到当前进程的二进制实体(文件):

继续回到exp中,下面构造了一个cap,改cap定义的permitted为0xffffffff,并且开启Effective,然后将/proc/self下的文件拷贝到merge文件夹下,根据overlay文件系统特性,这个拷贝过程实际是创建./ovlcap/upper/magic文件,最后调用setxattr()函数,将cap设置到./ovlcap/merge/magic上面。

根据前文漏洞原理介绍,权限逃逸后,此时属于ext3文件系统的./ovlcap/upper/magic文件的capabilitiy为all+ep,便可以利用capabilitiy进行权限提升,接着启动./ovlcap/upper/magic进程,该进程的capabilitiy已具备all+ep,然后进行setuid(0)和setgid(0)提权操作,这是被允许的。

07

补丁跟踪

漏洞成因在上面已经介绍了,这里的补丁也很彻底,将cap_convert_nscap放入了vfs_setxattr中,即每次进入vfs_setxattr()函数时,都先进行权限校验,判断capabilitiy和命名空间的权限是否匹配。

参考链接:

[1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3493

[2] https://access.redhat.com/security/cve/cve-2021-3493

[3] https://ubuntu.com/security/CVE-2021-3493

[4] https://github.com/briskets/CVE-2021-3493

[5] https://cve.report/CVE-2021-3493.pdf

[6] https://blog.csdn.net/qq_15770331/article/details/96699386

[7] https://lwn.net/Articles/671641/

[8] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1793458/comments/4

[9] https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/xenial/commit/?id=98a3740920f8f3362c1ac50598af2dc632f5051a

声明:本文来自ADLab,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。